|
@@ -47,11 +47,13 @@ import java.awt.font.TextAttribute;
|
47
|
47
|
import java.awt.font.TextHitInfo;
|
48
|
48
|
import java.awt.font.TextLayout;
|
49
|
49
|
import java.awt.image.BufferedImage;
|
|
50
|
+import java.io.IOException;
|
50
|
51
|
import java.text.AttributedCharacterIterator;
|
51
|
52
|
import java.text.AttributedString;
|
52
|
53
|
import java.util.HashMap;
|
53
|
54
|
import java.util.Map;
|
54
|
55
|
|
|
56
|
+import javax.imageio.ImageIO;
|
55
|
57
|
import javax.swing.JPanel;
|
56
|
58
|
import javax.swing.SwingUtilities;
|
57
|
59
|
import javax.swing.event.MouseInputListener;
|
|
@@ -96,6 +98,8 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
|
96
|
98
|
private ConfigManager manager;
|
97
|
99
|
/** Config domain. */
|
98
|
100
|
private String domain;
|
|
101
|
+ /** Background image option. */
|
|
102
|
+ private BackgroundOption backgroundOption;
|
99
|
103
|
|
100
|
104
|
/**
|
101
|
105
|
* Creates a new text pane canvas.
|
|
@@ -120,6 +124,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
|
120
|
124
|
addMouseMotionListener(this);
|
121
|
125
|
addComponentListener(this);
|
122
|
126
|
manager.addChangeListener(domain, "textpanebackground", this);
|
|
127
|
+ manager.addChangeListener(domain, "textpanebackgroundoption", this);
|
123
|
128
|
|
124
|
129
|
updateCachedSettings();
|
125
|
130
|
}
|
|
@@ -142,6 +147,7 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
|
142
|
147
|
}
|
143
|
148
|
g.setColor(textPane.getBackground());
|
144
|
149
|
g.fill(g.getClipBounds());
|
|
150
|
+ paintBackground(g);
|
145
|
151
|
paintOntoGraphics(g);
|
146
|
152
|
//g.drawImage(buffer, 0, 0, null);
|
147
|
153
|
}
|
|
@@ -164,26 +170,95 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
|
164
|
170
|
*/
|
165
|
171
|
private void paintBackground(final Graphics2D g) {
|
166
|
172
|
if (backgroundImage != null) {
|
167
|
|
- g.drawImage(backgroundImage, 0,
|
168
|
|
- 0, getBounds().width, getBounds().height, null);
|
|
173
|
+ switch (backgroundOption) {
|
|
174
|
+ case TILED:
|
|
175
|
+ paintTiledBackground(g);
|
|
176
|
+ break;
|
|
177
|
+ case SCALE:
|
|
178
|
+ paintStretchedBackground(g);
|
|
179
|
+ break;
|
|
180
|
+ case SCALE_ASPECT_RATIO:
|
|
181
|
+ paintStretchedAspectRatioBackground(g);
|
|
182
|
+ break;
|
|
183
|
+ case CENTER:
|
|
184
|
+ paintCenterBackground(g);
|
|
185
|
+ break;
|
|
186
|
+ default:
|
|
187
|
+ break;
|
|
188
|
+ }
|
169
|
189
|
} else {
|
170
|
|
- g.fill(getBounds());
|
|
190
|
+ paintNoBackground(g);
|
|
191
|
+ }
|
|
192
|
+ }
|
|
193
|
+
|
|
194
|
+ private void paintNoBackground(final Graphics2D g) {
|
|
195
|
+ g.fill(getBounds());
|
|
196
|
+ }
|
|
197
|
+
|
|
198
|
+ private void paintStretchedBackground(final Graphics2D g) {
|
|
199
|
+ g.drawImage(backgroundImage, 0, 0, getBounds().width,
|
|
200
|
+ getBounds().height, null);
|
|
201
|
+ }
|
|
202
|
+
|
|
203
|
+ private void paintCenterBackground(final Graphics2D g) {
|
|
204
|
+ final int x = (getBounds().width / 2) - (backgroundImage.getWidth(null) / 2);
|
|
205
|
+ final int y = (getBounds().height / 2) - (backgroundImage.getHeight(null) / 2);
|
|
206
|
+ g.drawImage(backgroundImage, x, y, backgroundImage.getWidth(null),
|
|
207
|
+ backgroundImage.getWidth(null), null);
|
|
208
|
+ }
|
|
209
|
+
|
|
210
|
+ private void paintStretchedAspectRatioBackground(final Graphics2D g) {
|
|
211
|
+ final double widthratio = getBounds().width
|
|
212
|
+ / (double) backgroundImage.getWidth(null);
|
|
213
|
+ final double heightratio = getBounds().height
|
|
214
|
+ / (double) backgroundImage.getHeight(null);
|
|
215
|
+ final double ratio = Math.min(widthratio, heightratio);
|
|
216
|
+ final int width = (int) (backgroundImage.getWidth(null) * ratio);
|
|
217
|
+ final int height = (int) (backgroundImage.getWidth(null) * ratio);
|
|
218
|
+
|
|
219
|
+ final int x = (getBounds().width / 2) - (width / 2);
|
|
220
|
+ final int y = (getBounds().height / 2) - (height / 2);
|
|
221
|
+ g.drawImage(backgroundImage, x, y, width, height, null);
|
|
222
|
+ }
|
|
223
|
+
|
|
224
|
+ private void paintTiledBackground(final Graphics2D g) {
|
|
225
|
+ final int width = backgroundImage.getWidth(null);
|
|
226
|
+ final int height = backgroundImage.getWidth(null);
|
|
227
|
+
|
|
228
|
+ if (width <= 0 || height <= 0) {
|
|
229
|
+ // ARG!
|
|
230
|
+ return;
|
|
231
|
+ }
|
|
232
|
+
|
|
233
|
+ for (int x = 0; x < getBounds().width; x += width) {
|
|
234
|
+ for (int y = 0; y < getBounds().height; y += height) {
|
|
235
|
+ g.drawImage(backgroundImage, x, y, width, height, null);
|
|
236
|
+ }
|
171
|
237
|
}
|
172
|
238
|
}
|
173
|
239
|
|
174
|
240
|
private void updateCachedSettings() {
|
175
|
241
|
final String backgroundPath = manager.getOption(domain,
|
176
|
242
|
"textpanebackground");
|
177
|
|
- UIUtilities.invokeLater(new Runnable() {
|
|
243
|
+ UIUtilities.invokeAndWait(new Runnable() {
|
178
|
244
|
|
179
|
245
|
/** {@inheritDoc} */
|
180
|
246
|
@Override
|
181
|
247
|
public void run() {
|
182
|
|
- backgroundImage = backgroundPath.isEmpty() ? null : Toolkit.
|
183
|
|
- getDefaultToolkit().createImage(URLBuilder.buildURL(backgroundPath));
|
184
|
|
- repaint();
|
|
248
|
+ try {
|
|
249
|
+ backgroundImage = ImageIO.read(URLBuilder.
|
|
250
|
+ buildURL(backgroundPath));
|
|
251
|
+ } catch (IOException ex) {
|
|
252
|
+ backgroundImage = null;
|
|
253
|
+ }
|
185
|
254
|
}
|
186
|
255
|
});
|
|
256
|
+ try {
|
|
257
|
+ backgroundOption = BackgroundOption.valueOf(manager.getOption(domain,
|
|
258
|
+ "textpanebackgroundoption"));
|
|
259
|
+ } catch (IllegalArgumentException ex) {
|
|
260
|
+ backgroundOption = BackgroundOption.CENTER;
|
|
261
|
+ }
|
187
|
262
|
}
|
188
|
263
|
|
189
|
264
|
/**
|
|
@@ -216,9 +291,6 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
|
216
|
291
|
int paragraphEnd;
|
217
|
292
|
LineBreakMeasurer lineMeasurer;
|
218
|
293
|
|
219
|
|
- g.setColor(textPane.getBackground());
|
220
|
|
- paintBackground(g);
|
221
|
|
-
|
222
|
294
|
textLayouts.clear();
|
223
|
295
|
positions.clear();
|
224
|
296
|
|