1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.components;
21
22 import com.cosylab.gui.components.util.FontHelper;
23 import com.cosylab.gui.components.util.PaintHelper;
24
25 import com.cosylab.logging.DebugLogger;
26
27 import java.awt.Dimension;
28 import java.awt.Font;
29 import java.awt.Graphics;
30 import java.awt.Graphics2D;
31 import java.awt.Insets;
32 import java.awt.event.ComponentAdapter;
33 import java.awt.event.ComponentEvent;
34 import java.awt.event.HierarchyEvent;
35 import java.awt.event.HierarchyListener;
36 import java.awt.event.KeyAdapter;
37 import java.awt.event.KeyEvent;
38
39 import java.util.logging.Level;
40 import java.util.logging.Logger;
41
42 import javax.swing.JTextField;
43 import javax.swing.text.Document;
44
45
46
47
48
49
50
51
52
53
54
55
56 public class ResizableTextField extends JTextField
57 {
58 private static final long serialVersionUID = 1L;
59 private boolean resizable;
60 private boolean enhanced;
61 private Dimension preferredSize;
62 private Dimension minimumSize;
63 private Font userFont;
64 private final Logger logger = DebugLogger.getLogger("RTF", Level.OFF);
65
66
67
68
69 public ResizableTextField()
70 {
71 this(null, null, 0);
72 }
73
74
75
76
77
78
79 public ResizableTextField(String arg0)
80 {
81 this(null, arg0, 0);
82 }
83
84
85
86
87
88
89 public ResizableTextField(int arg0)
90 {
91 this(null, null, arg0);
92 }
93
94
95
96
97
98
99
100
101 public ResizableTextField(String arg0, int arg1)
102 {
103 this(null, arg0, arg1);
104 }
105
106
107
108
109
110
111
112
113
114 public ResizableTextField(Document arg0, String arg1, int arg2)
115 {
116 super(arg0, arg1, arg2);
117 addComponentListener(new ResizableComponentAdapter());
118 addHierarchyListener(new ResizableComponentAdapter());
119 addKeyListener(new ResizableKeyAdapter());
120 setFont(FontHelper.getDefaultFont());
121 }
122
123
124
125
126
127
128 public boolean isResizable()
129 {
130 return resizable;
131 }
132
133
134
135
136
137
138
139 public void setResizable(boolean newResizable)
140 {
141 boolean oldResizable = resizable;
142
143 if (oldResizable == newResizable) {
144 return;
145 }
146
147 resizable = newResizable;
148 firePropertyChange("resizable", oldResizable, newResizable);
149
150 if (resizable) {
151 resize();
152 } else {
153 if (userFont != null) {
154 super.setFont(userFont);
155 } else {
156 super.setFont(FontHelper.getDefaultFont());
157 }
158
159
160
161 }
162 }
163
164
165
166
167
168
169
170 public void setEnhanced(boolean newEnhanced)
171 {
172 boolean oldEnhanced = enhanced;
173
174 if (oldEnhanced == newEnhanced) {
175 return;
176 }
177
178 enhanced = newEnhanced;
179 firePropertyChange("enhanced", oldEnhanced, newEnhanced);
180 repaint();
181 }
182
183
184
185
186
187
188 public boolean isEnhanced()
189 {
190 return enhanced;
191 }
192
193
194
195
196
197
198
199
200 public void setMargin(Insets margin)
201 {
202 if (margin == null) {
203 super.setMargin(new Insets(0, 2, 0, 2));
204
205 return;
206 }
207
208 if (margin.left == 0) {
209 super.setMargin(new Insets(margin.top, 2, margin.bottom,
210 margin.right));
211
212 return;
213 }
214
215 super.setMargin(margin);
216 }
217
218
219
220
221
222
223
224
225 public void setText(String text)
226 {
227 if (logger!=null) logger.info("text='" + text + "'");
228 super.setText(text);
229
230
231
232 }
233
234
235
236
237
238 protected void resize()
239 {
240 if (!isResizable()) {
241 return;
242 }
243
244
245 logger.fine("resizing");
246
247
248
249
250
251
252
253
254
255
256 Font f = FontHelper.calculateFittingFont(this, getFont(), getText(),
257 getColumns(), 0, Integer.MAX_VALUE);
258
259 if (f != getFont()) {
260 logger.fine("font resized to " + f.getSize() + " from "
261 + getFont().getSize());
262 super.setFont(f);
263 }
264 }
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297 public Dimension getPreferredSize()
298 {
299 if (preferredSize != null) {
300 return preferredSize;
301 }
302
303 Font font = FontHelper.getDefaultFont();
304 int height = (font.getSize() * 20) / 13;
305 int width = (getColumns() * getFontMetrics(font).stringWidth("m") * 10) / 8;
306
307 return new Dimension(Math.max(width, 1), Math.max(height, 1));
308 }
309
310
311
312
313
314
315 public void setPreferredSize(Dimension newPreferredSize)
316 {
317 preferredSize = newPreferredSize;
318 super.setPreferredSize(newPreferredSize);
319 }
320
321
322
323
324
325
326 public Dimension getMinimumSize()
327 {
328 if (minimumSize != null) {
329 return minimumSize;
330 }
331
332 Font font = FontHelper.getDefaultFont();
333 int height = (font.getSize() * 20) / 13;
334 int width = (getColumns() * getFontMetrics(font).stringWidth("m") * 10) / 8;
335
336 return new Dimension(Math.max(width, 1), Math.max(height, 1));
337 }
338
339
340
341
342
343
344 public void setMinimumSize(Dimension newMinimumSize)
345 {
346 minimumSize = newMinimumSize;
347 super.setMinimumSize(newMinimumSize);
348 }
349
350
351
352
353
354
355
356
357
358 protected void paintComponent(Graphics g)
359 {
360
361 logger.fine("painting");
362
363 if (enhanced) {
364 ((Graphics2D)g).addRenderingHints(PaintHelper.getAntialiasingHints());
365 }
366
367 super.paintComponent(g);
368 }
369
370
371
372
373
374
375
376 public void setFont(Font f)
377 {
378 userFont = f;
379 super.setFont(f);
380 }
381
382
383
384
385
386
387
388 protected class ResizableComponentAdapter extends ComponentAdapter implements HierarchyListener
389 {
390
391
392
393
394
395
396
397 public void componentResized(ComponentEvent e)
398 {
399 logger.finest("resize event " + e);
400 resize();
401 }
402
403
404
405
406
407
408
409
410 public void hierarchyChanged(HierarchyEvent e) {
411 resize();
412 }
413 }
414
415
416
417
418
419
420
421 protected class ResizableKeyAdapter extends KeyAdapter
422 {
423
424
425
426
427
428
429
430 public void keyReleased(KeyEvent e)
431 {
432 if (resizable) {
433 revalidate();
434 resize();
435 }
436 }
437 }
438 }
439
440