1 /* -------------------------------------------------------------------
2 * Java source file for the class OrientedLabel
3 *
4 * Copyright (c), 2002, Masahiro Takatsuka.
5 * All Rights Researved.
6 *
7 * Original Author: Masahiro Takatsuka (masa@jbeans.net)
8 * $Author: takatsukam $
9 *
10 * $Date: 2003/07/25 04:51:47 $
11 *
12 * $Id: OrientedLabel.java,v 1.1.1.1 2003/07/25 04:51:47 takatsukam Exp $
13 *
14 * Reference: Document no:
15 * ___ ___
16 *
17 * To Do:
18 * ___
19 *
20 ------------------------------------------------------------------- */
21
22 /* --------------------------- Package ---------------------------- */
23 package net.jbeans.ui.label;
24
25 /* ------------------ Import classes (packages) ------------------- *//package-summary/html">color="#329900"> ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900"> ------------------ Import classes (packages) ------------------- */
26 import java.awt.*;
27 import java.awt.event.*;
28 import java.awt.geom.*;
29 import java.io.*;
30 import javax.swing.*;
31 import javax.swing.plaf.*;
32
33 /*====================================================================
34 Implementation of class OrientedLabel
35 ====================================================================*/
36 /***
37 * OrientedLabel is a display area for a short text string or an image,
38 * or both. A label does not react to input events. As a result,
39 * it cannot get the keyboard focus. You can specify the orientation
40 * of OrientedLabel object.
41 *
42 * @version $Revision: 1.1.1.1 $
43 * @author Masahiro Takatsuka (masa@jbeans.net)
44 * @see JLabel
45 * @see Serializable
46 */
47
48 public class OrientedLabel extends JLabel implements Serializable {
49 /***
50 * A rotation angle.
51 */
52 private double angle = 0.0;
53
54 /***
55 * The center of Rotation .
56 */
57 private int rotCenter = CENTER;
58
59 /***
60 * the center of rotation.
61 */
62 private double[] center = new double[2];
63
64 /***
65 * the amount of translation.
66 */
67 private double[] offset = new double[2];
68
69 /***
70 * The width of Label after rotaion.
71 */
72 private int myWidth = 0;
73
74 /***
75 * The height of Label after rotaion.
76 */
77 private int myHeight = 0;
78
79 /***
80 * A flag to indicate necessity of computation of size, center, offset
81 * or not.
82 */
83 private boolean needToComputeSize = true;
84
85 /*
86 * temp. buffer for fast computation.
87 */
88 private double[] cornersSrc = new double[8];
89 private double[] cornersDst = new double[8];
90 private AffineTransform at = new AffineTransform();
91
92 /***
93 * Creates an <code>OrientedLabel</code> instance with
94 * no image and with an empty string for the title.
95 * The label is centered vertically
96 * in its display area.
97 * The label's contents, once set, will be displayed on the leading edge
98 * of the label's display area.
99 */
100 public OrientedLabel() {
101 super();
102 }
103
104 /***
105 * Creates an <code>OrientedLabel</code> instance with the specified image.
106 * The label is centered vertically and horizontally
107 * in its display area.
108 *
109 * @param icon The image to be displayed by the label.
110 */
111 public OrientedLabel(Icon image) {
112 super(image);
113 }
114
115 /***
116 * Creates an <code>OrientedLabel</code> instance with the specified
117 * image and horizontal alignment.
118 * The label is centered vertically in its display area.
119 *
120 * @param icon The image to be displayed by the label.
121 * @param horizontalAlignment One of the following constants
122 * defined in <code>SwingConstants</code>:
123 * <code>LEFT</code>,
124 * <code>CENTER</code>,
125 * <code>RIGHT</code>,
126 * <code>LEADING</code> or
127 * <code>TRAILING</code>.
128 */
129 public OrientedLabel(Icon image, int horizontalAlignment) {
130 super(image, horizontalAlignment);
131 }
132
133 /***
134 * Creates an <code>OrientedLabel</code> instance with the specified text.
135 * The label is aligned against the leading edge of its display area,
136 * and centered vertically.
137 *
138 * @param text The text to be displayed by the label.
139 */
140 public OrientedLabel(String text) {
141 super(text);
142 }
143
144 /*
145 * Creates an <code>OrientedLabel</code> instance with the specified
146 * text, image, and horizontal alignment.
147 * The label is centered vertically in its display area.
148 * The text is on the trailing edge of the image.
149 *
150 * @param text The text to be displayed by the label.
151 * @param icon The image to be displayed by the label.
152 * @param horizontalAlignment One of the following constants
153 * defined in <code>SwingConstants</code>:
154 * <code>LEFT</code>,
155 * <code>CENTER</code>,
156 * <code>RIGHT</code>,
157 * <code>LEADING</code> or
158 * <code>TRAILING</code>.
159 */
160 public OrientedLabel(String text, Icon image, int horizontalAlignment) {
161 super(text, image, horizontalAlignment);
162 }
163
164 /***
165 * Creates an <code>OrientedLabel</code> instance with the specified
166 * text and horizontal alignment.
167 * The label is centered vertically in its display area.
168 *
169 * @param text The text to be displayed by the label.
170 * @param horizontalAlignment One of the following constants
171 * defined in <code>SwingConstants</code>:
172 * <code>LEFT</code>,
173 * <code>CENTER</code>,
174 * <code>RIGHT</code>,
175 * <code>LEADING</code> or
176 * <code>TRAILING</code>.
177 */
178 public OrientedLabel(String text, int horizontalAlignment) {
179 super(text, horizontalAlignment);
180 }
181
182 /***
183 * Sets a rotation angle.
184 *
185 * @param angle the rotation angle in radian.
186 */
187 public void setAngle(double angle) {
188 this.angle = angle;
189 this.needToComputeSize = true;
190 }
191
192 /***
193 * Gets a rotation angle.
194 *
195 * @return a rotation angle in radian.
196 */
197 public double getAngle() {
198 return this.angle;
199 }
200
201 // /***
202 // * Calls paint(g). Doesn't clear the background.
203 // *
204 // * @see #paint
205 // */
206 // public void update(Graphics g) {
207 // paint(g);
208 // }
209
210 /***
211 * Computes the center of rotation and translation offsets.
212 */
213 private void computeCenterOffset() {
214 this.center[0] = this.myWidth / 2.0;
215 this.center[1] = this.myHeight / 2.0;
216 Dimension pdim = super.getPreferredSize();
217 int aliX = getHorizontalAlignment();
218 int aliY = getVerticalAlignment();
219 switch (aliX) {
220 case CENTER:
221 this.offset[0] = 0;
222 break;
223 case LEFT:
224 case LEADING:
225 this.offset[0] = - (this.center[0] - pdim.width / 2.0);
226 case RIGHT:
227 case TRAILING:
228 this.offset[0] = this.center[0] - pdim.width / 2.0;
229 break;
230 }
231 switch (aliY) {
232 case CENTER:
233 this.offset[1] = 0;
234 break;
235 case TOP:
236 this.offset[1] = - (this.center[1] - pdim.height / 2.0);
237 case BOTTOM:
238 this.offset[1] = this.center[1] - pdim.height / 2.0;
239 break;
240 }
241 }
242
243 /***
244 * Computes the center of rotation and translation offsets.
245 */
246 private void computeSize() {
247 if (! this.needToComputeSize) {
248 return;
249 }
250 Dimension pdim = super.getPreferredSize();
251 int w = pdim.width;
252 int h = pdim.height;
253 double wc = w / 2.0;
254 double hc = h / 2.0;
255 this.center[0] = wc;
256 this.center[1] = hc;
257 this.at.setToRotation(- this.angle, wc, hc);
258 this.cornersSrc[0] = 0; this.cornersSrc[1] = 0;
259 this.cornersSrc[2] = 0; this.cornersSrc[3] = h;
260 this.cornersSrc[4] = w; this.cornersSrc[5] = h;
261 this.cornersSrc[6] = w; this.cornersSrc[7] = 0;
262 int maxw, minw, maxh, minh;
263 maxw = maxh = -Integer.MAX_VALUE;
264 minw = minh = Integer.MAX_VALUE;
265 this.at.transform(this.cornersSrc, 0, this.cornersDst, 0, 4);
266 for (int i = 0; i < 4; i++) {
267 if (this.cornersDst[i * 2 + 0] < minw) {
268 minw = (int) this.cornersDst[i * 2 + 0];
269 }
270 if (this.cornersDst[i * 2 + 0] > maxw) {
271 maxw = (int) this.cornersDst[i * 2 + 0];
272 }
273 if (this.cornersDst[i * 2 + 1] < minh) {
274 minh = (int) this.cornersDst[i * 2 + 1];
275 }
276 if (this.cornersDst[i * 2 + 1] > maxh) {
277 maxh = (int) this.cornersDst[i * 2 + 1];
278 }
279 }
280 this.myWidth = maxw - minw;
281 this.myHeight = maxh - minh;
282 this.myWidth = (this.myWidth > w) ? this.myWidth : w;
283 this.myHeight = (this.myHeight > h) ? this.myHeight : h;
284 computeCenterOffset();
285 this.needToComputeSize = false;
286 }
287
288 /***
289 * paints Label object.
290 */
291 public void paint(Graphics g) {
292 Graphics2D g2d = (Graphics2D) g;
293
294 /*
295 following four lines are for debug.
296 Rectangle rec = getBounds();
297 g2d.drawRect(0, 0, rec.width, rec.height);
298 g2d.drawLine(0, rec.height / 2, rec.width, rec.height / 2);
299 g2d.drawLine(rec.width / 2, 0, rec.width / 2, rec.height);
300 */
301
302 g2d.rotate(- this.angle, this.center[0], this.center[1]);
303 g2d.translate(this.offset[0], this.offset[1]);
304 super.paint(g);
305 }
306
307 /***
308 * Returns the preferred size of this container.
309 */
310 public Dimension getPreferredSize() {
311 computeSize();
312 return new Dimension(this.myWidth, this.myHeight);
313 }
314
315 /***
316 * Returns the minimum size.
317 */
318 public Dimension getMinimumSize() {
319 return getPreferredSize();
320 }
321
322 /***
323 * Sets the L&F object that renders this component.
324 *
325 * @param ui the LabelUI L&F object
326 * @see UIDefaults#getUI
327 * @beaninfo
328 * expert: true
329 * description: The L&F object that renders this component.
330 */
331 public void setUI(LabelUI ui) {
332 this.needToComputeSize = true;
333 super.setUI(ui);
334 }
335
336 /***
337 * Defines the single line of text this component will display. If
338 * the value of text is null or empty string, nothing is displayed.
339 * <p>
340 * The default value of this property is null.
341 * <p>
342 * This is a JavaBeans bound property.
343 *
344 * @see #setVerticalTextPosition
345 * @see #setHorizontalTextPosition
346 * @see #setIcon
347 * @beaninfo
348 * preferred: true
349 * bound: true
350 * attribute: visualUpdate true
351 * description: Defines the single line of text this component will display.
352 */
353 public void setText(String text) {
354 this.needToComputeSize = true;
355 super.setText(text);
356 }
357
358 /***
359 * Defines the icon this component will display. If
360 * the value of icon is null, nothing is displayed.
361 * <p>
362 * The default value of this property is null.
363 * <p>
364 * This is a JavaBeans bound property.
365 *
366 * @see #setVerticalTextPosition
367 * @see #setHorizontalTextPosition
368 * @see #getIcon
369 * @beaninfo
370 * preferred: true
371 * bound: true
372 * attribute: visualUpdate true
373 * description: The icon this component will display.
374 */
375 public void setIcon(Icon icon) {
376 this.needToComputeSize = true;
377 super.setIcon(icon);
378 }
379
380 /***
381 * Set the icon to be displayed if this JLabel is "disabled"
382 * (JLabel.setEnabled(false)).
383 * <p>
384 * The default value of this property is null.
385 *
386 * @param disabledIcon the Icon to display when the component is disabled
387 * @see #getDisabledIcon
388 * @see #setEnabled
389 * @beaninfo
390 * bound: true
391 * attribute: visualUpdate true
392 * description: The icon to display if the label is disabled.
393 */
394 public void setDisabledIcon(Icon disabledIcon) {
395 this.needToComputeSize = true;
396 super.setDisabledIcon(disabledIcon);
397 }
398
399 /***
400 * Specify a keycode that indicates a mnemonic key.
401 * This property is used when the label is part of a larger component.
402 * If the labelFor property of the label is not null, the label will
403 * call the requestFocus method of the component specified by the
404 * labelFor property when the mnemonic is activated.
405 *
406 * @see #getLabelFor
407 * @see #setLabelFor
408 * @beaninfo
409 * bound: true
410 * attribute: visualUpdate true
411 * description: The mnemonic keycode.
412 */
413 public void setDisplayedMnemonic(int key) {
414 this.needToComputeSize = true;
415 super.setDisplayedMnemonic(key);
416 }
417
418 /***
419 * Specifies the displayedMnemonic as a char value.
420 *
421 * @param aChar a char specifying the mnemonic to display
422 * @see #setDisplayedMnemonic(int)
423 */
424 public void setDisplayedMnemonic(char aChar) {
425 this.needToComputeSize = true;
426 super.setDisplayedMnemonic(aChar);
427 }
428
429 /***
430 * If both the icon and text properties are set, this property
431 * defines the space between them.
432 * <p>
433 * The default value of this property is 4 pixels.
434 * <p>
435 * This is a JavaBeans bound property.
436 *
437 * @see #getIconTextGap
438 * @beaninfo
439 * bound: true
440 * attribute: visualUpdate true
441 * description: If both the icon and text properties are set, this
442 * property defines the space between them.
443 */
444 public void setIconTextGap(int iconTextGap) {
445 this.needToComputeSize = true;
446 super.setIconTextGap(iconTextGap);
447 }
448
449 /***
450 * Sets the alignment of the label's contents along the Y axis.
451 * <p>
452 * The default value of this property is CENTER.
453 *
454 * @param alignment One of the following constants
455 * defined in <code>SwingConstants</code>:
456 * <code>TOP</code>,
457 * <code>CENTER</code> (the default), or
458 * <code>BOTTOM</code>.
459 *
460 * @see SwingConstants
461 * @see #getVerticalAlignment
462 * @beaninfo
463 * bound: true
464 * enum: TOP SwingConstants.TOP
465 * CENTER SwingConstants.CENTER
466 * BOTTOM SwingConstants.BOTTOM
467 * attribute: visualUpdate true
468 * description: The alignment of the label's contents along the Y axis.
469 */
470 public void setVerticalAlignment(int alignment) {
471 this.needToComputeSize = true;
472 super.setVerticalAlignment(alignment);
473 }
474
475 /***
476 * Sets the alignment of the label's contents along the X axis.
477 * <p>
478 * This is a JavaBeans bound property.
479 *
480 * @param alignment One of the following constants
481 * defined in <code>SwingConstants</code>:
482 * <code>LEFT</code>,
483 * <code>CENTER</code> (the default for image-only labels),
484 * <code>RIGHT</code>,
485 * <code>LEADING</code> (the default for text-only labels) or
486 * <code>TRAILING</code>.
487 *
488 * @see SwingConstants
489 * @see #getHorizontalAlignment
490 * @beaninfo
491 * bound: true
492 * enum: LEFT SwingConstants.LEFT
493 * CENTER SwingConstants.CENTER
494 * RIGHT SwingConstants.RIGHT
495 * LEADING SwingConstants.LEADING
496 * TRAILING SwingConstants.TRAILING
497 * attribute: visualUpdate true
498 * description: The alignment of the label's content along the X axis.
499 */
500 public void setHorizontalAlignment(int alignment) {
501 this.needToComputeSize = true;
502 super.setHorizontalAlignment(alignment);
503 }
504
505 /***
506 * Sets the vertical position of the label's text,
507 * relative to its image.
508 * <p>
509 * The default value of this property is CENTER.
510 * <p>
511 * This is a JavaBeans bound property.
512 *
513 * @param textPosition One of the following constants
514 * defined in <code>SwingConstants</code>:
515 * <code>TOP</code>,
516 * <code>CENTER</code> (the default), or
517 * <code>BOTTOM</code>.
518 *
519 * @see SwingConstants
520 * @see #getVerticalTextPosition
521 * @beaninfo
522 * bound: true
523 * enum: TOP SwingConstants.TOP
524 * CENTER SwingConstants.CENTER
525 * BOTTOM SwingConstants.BOTTOM
526 * expert: true
527 * attribute: visualUpdate true
528 * description: The vertical position of the text relative to it's image.
529 */
530 public void setVerticalTextPosition(int textPosition) {
531 this.needToComputeSize = true;
532 super.setVerticalTextPosition(textPosition);
533 }
534
535 /***
536 * Sets the horizontal position of the label's text,
537 * relative to its image.
538 *
539 * @param x One of the following constants
540 * defined in <code>SwingConstants</code>:
541 * <code>LEFT</code>,
542 * <code>CENTER</code>,
543 * <code>RIGHT</code>,
544 * <code>LEADING</code>, or
545 * <code>TRAILING</code> (the default).
546 * @exception IllegalArgumentException
547 *
548 * @see SwingConstants
549 * @beaninfo
550 * expert: true
551 * bound: true
552 * enum: LEFT SwingConstants.LEFT
553 * CENTER SwingConstants.CENTER
554 * RIGHT SwingConstants.RIGHT
555 * LEADING SwingConstants.LEADING
556 * TRAILING SwingConstants.TRAILING
557 * attribute: visualUpdate true
558 * description: The horizontal position of the label's text,
559 * relative to its image.
560 */
561 public void setHorizontalTextPosition(int textPosition) {
562 this.needToComputeSize = true;
563 super.setHorizontalTextPosition(textPosition);
564 }
565
566 /***
567 * Set the component this is labelling. Can be null if this does not
568 * label a Component. If the displayedMnemonic property is set
569 * and the labelFor property is also set, the label will
570 * call the requestFocus method of the component specified by the
571 * labelFor property when the mnemonic is activated.
572 *
573 * @param c the Component this label is for, or null if the label is
574 * not the label for a component
575 *
576 * @see #getDisplayedMnemonic
577 * @see #setDisplayedMnemonic
578 *
579 * @beaninfo
580 * bound: true
581 * description: The component this is labelling.
582 */
583 public void setLabelFor(Component c) {
584 this.needToComputeSize = true;
585 super.setLabelFor(c);
586 }
587 }
588
This page was automatically generated by Maven