fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / libjava / javax / swing / border / TitledBorder.java
blob3b6a791630c57f4d530060fdfc46f8a6898d0ee8
1 /* TitledBorder.java --
2 Copyright (C) 2003 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.border;
41 import java.awt.Color;
42 import java.awt.Component;
43 import java.awt.Dimension;
44 import java.awt.Font;
45 import java.awt.FontMetrics;
46 import java.awt.Graphics;
47 import java.awt.Insets;
48 import java.awt.Rectangle;
49 import java.awt.Shape;
50 import javax.swing.UIManager;
53 /**
54 * A border that paints a title on top of another border.
56 * @author Sascha Brawer (brawer@dandelis.ch)
58 public class TitledBorder
59 extends AbstractBorder
61 /**
62 * A value for the <code>titlePosition</code> property that vertically
63 * positions the title text at the default vertical position, which
64 * is in the middle of the top line of the border.
66 * @see #getTitlePosition()
67 * @see #setTitlePosition(int)
69 public static final int DEFAULT_POSITION = 0;
72 /**
73 * A value for the <code>titlePosition</code> property that vertically
74 * positions the title text above the top line of the border.
76 * @see #getTitlePosition()
77 * @see #setTitlePosition(int)
79 public static final int ABOVE_TOP = 1;
82 /**
83 * A value for the <code>titlePosition</code> property that vertically
84 * positions the title text at the middle of the top line
85 * of the border.
87 * @see #getTitlePosition()
88 * @see #setTitlePosition(int)
90 public static final int TOP = 2;
93 /**
94 * A value for the <code>titlePosition</code> property that vertically
95 * positions the title text below the top line of the border.
97 * @see #getTitlePosition()
98 * @see #setTitlePosition(int)
100 public static final int BELOW_TOP = 3;
104 * A value for the <code>titlePosition</code> property that vertically
105 * positions the title text above the bottom line of the border.
107 * @see #getTitlePosition()
108 * @see #setTitlePosition(int)
110 public static final int ABOVE_BOTTOM = 4;
114 * A value for the <code>titlePosition</code> property that vertically
115 * positions the title text at the center of the bottom line
116 * of the border.
118 * @see #getTitlePosition()
119 * @see #setTitlePosition(int)
121 public static final int BOTTOM = 5;
125 * A value for the <code>titlePosition</code> property that vertically
126 * positions the title text below the bottom line of the border.
128 * @see #getTitlePosition()
129 * @see #setTitlePosition(int)
131 public static final int BELOW_BOTTOM = 6;
135 * A value for the <code>titleJustification</code> property that
136 * horizontally aligns the title text with either the left or the
137 * right edge of the border, depending on the orientation of the
138 * component nested into the border. If the component orientation
139 * is left-to-right, the title text is aligned with the left edge;
140 * otherwise, it is aligned with the right edge. This is the same
141 * behavior as with {@link #LEADING}.
143 * @see #getTitleJustification()
144 * @see #setTitleJustification(int)
145 * @see java.awt.ComponentOrientation#isLeftToRight()
147 public static final int DEFAULT_JUSTIFICATION = 0;
151 * A value for the <code>titleJustification</code> property that
152 * horizontally aligns the title text with the left-hand edge of
153 * the border.
155 * @see #getTitleJustification()
156 * @see #setTitleJustification(int)
158 public static final int LEFT = 1;
162 * A value for the <code>titleJustification</code> property that
163 * horizontally aligns the title text with the center of the border.
165 * @see #getTitleJustification()
166 * @see #setTitleJustification(int)
168 public static final int CENTER = 2;
172 * A value for the <code>titleJustification</code> property that
173 * horizontally aligns the title text with the right-hand edge of
174 * the border.
176 * @see #getTitleJustification()
177 * @see #setTitleJustification(int)
179 public static final int RIGHT = 3;
183 * A value for the <code>titleJustification</code> property that
184 * horizontally aligns the title text with either the left or the
185 * right edge of the border, depending on the orientation of the
186 * component nested into the border. If the component orientation
187 * is left-to-right, the title text is aligned with the left edge;
188 * otherwise, it is aligned with the right edge. This is the same
189 * behavior as with {@link #DEFAULT_JUSTIFICATION}.
191 * @see #getTitleJustification()
192 * @see #setTitleJustification(int)
193 * @see java.awt.ComponentOrientation#isLeftToRight()
195 public static final int LEADING = 4;
199 * A value for the <code>titleJustification</code> property that
200 * horizontally aligns the title text with either the right or the
201 * left edge of the border, depending on the orientation of the
202 * component nested into the border. If the component orientation
203 * is left-to-right, the title text is aligned with the right edge;
204 * otherwise, it is aligned with the left edge.
206 * @see #getTitleJustification()
207 * @see #setTitleJustification(int)
208 * @see java.awt.ComponentOrientation#isLeftToRight()
210 public static final int TRAILING = 5;
214 * The number of pixels between the inside of {@link #border}
215 * and the bordered component.
217 protected static final int EDGE_SPACING = 2;
221 * The number of pixels between the outside of this TitledBorder
222 * and the beginning (if left-aligned) or end (if right-aligned)
223 * of the title text.
225 protected static final int TEXT_INSET_H = 5;
229 * The number of pixels between the title text and {@link #border}.
230 * This value is only relevant if the title text does not intersect
231 * {@link #border}. No intersection occurs if {@link #titlePosition}
232 * is one of {@link #ABOVE_TOP}, {@link #BELOW_TOP}, {@link #ABOVE_BOTTOM},
233 * or {@link #BELOW_BOTTOM}.
235 protected static final int TEXT_SPACING = 2;
239 * Determined using the <code>serialver</code> tool of Apple/Sun JDK 1.3.1
240 * on MacOS X 10.1.5.
242 static final long serialVersionUID = 8012999415147721601L;
246 * The title, or <code>null</code> to display no title.
248 protected String title;
252 * The border underneath the title. If this value is
253 * <code>null</code>, the border will be retrieved from the {@link
254 * javax.swing.UIManager}&#x2019;s defaults table using the key
255 * <code>&quot;TitledBorder.border&quot;</code>.
257 protected Border border;
261 * The vertical position of the title text relative to the border,
262 * which is one of {@link #ABOVE_TOP}, {@link #TOP}, {@link
263 * #BELOW_TOP}, {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link
264 * #BELOW_BOTTOM}, or {@link #DEFAULT_POSITION}.
266 protected int titlePosition;
270 * The horizontal alignment of the title text in relation to the
271 * border, which is one of {@link #LEFT}, {@link #CENTER}, {@link
272 * #RIGHT}, {@link #LEADING}, {@link #TRAILING}, or {@link
273 * #DEFAULT_JUSTIFICATION}.
275 protected int titleJustification;
279 * The font for displaying the title text. If this value is
280 * <code>null</code>, the font will be retrieved from the {@link
281 * javax.swing.UIManager}&#x2019;s defaults table using the key
282 * <code>&quot;TitledBorder.font&quot;</code>.
284 protected Font titleFont;
288 * The color for displaying the title text. If this value is
289 * <code>null</code>, the color will be retrieved from the {@link
290 * javax.swing.UIManager}&#x2019;s defaults table using the key
291 * <code>&quot;TitledBorder.titleColor&quot;</code>.
293 protected Color titleColor;
297 * Constructs a TitledBorder given the text of its title.
299 * @param title the title text, or <code>null</code> to use no title text.
301 public TitledBorder(String title)
303 this(/* border */ null,
304 title, DEFAULT_JUSTIFICATION, DEFAULT_POSITION,
305 /* titleFont */ null, /* titleColor */ null);
310 * Constructs an initially untitled TitledBorder given another border.
312 * @param border the border underneath the title, or <code>null</code>
313 * to use a default from the current look and feel.
315 public TitledBorder(Border border)
317 this(border, /* title */ "", DEFAULT_JUSTIFICATION, DEFAULT_POSITION,
318 /* titleFont */ null, /* titleColor */ null);
323 * Constructs a TitledBorder given its border and title text.
325 * @param border the border underneath the title, or <code>null</code>
326 * to use a default from the current look and feel.
328 * @param title the title text, or <code>null</code> to use no title
329 * text.
331 public TitledBorder(Border border, String title)
333 this(border, title, DEFAULT_JUSTIFICATION, DEFAULT_POSITION,
334 /* titleFont */ null, /* titleColor */ null);
339 * Constructs a TitledBorder given its border, title text, horizontal
340 * alignment, and vertical position.
342 * @param border the border underneath the title, or <code>null</code>
343 * to use a default from the current look and feel.
345 * @param title the title text, or <code>null</code> to use no title
346 * text.
348 * @param titleJustification the horizontal alignment of the title
349 * text in relation to the border. The value must be one of
350 * {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, {@link #LEADING},
351 * {@link #TRAILING}, or {@link #DEFAULT_JUSTIFICATION}.
353 * @param titlePosition the vertical position of the title text
354 * in relation to the border. The value must be one of
355 * {@link #ABOVE_TOP}, {@link #TOP}, {@link #BELOW_TOP},
356 * {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link #BELOW_BOTTOM},
357 * or {@link #DEFAULT_POSITION}.
359 * @throws IllegalArgumentException if <code>titleJustification</code>
360 * or <code>titlePosition</code> have an unsupported value.
362 public TitledBorder(Border border, String title, int titleJustification,
363 int titlePosition)
365 this(border, title, titleJustification, titlePosition,
366 /* titleFont */ null, /* titleColor */ null);
371 * Constructs a TitledBorder given its border, title text, horizontal
372 * alignment, vertical position, and font.
374 * @param border the border underneath the title, or <code>null</code>
375 * to use a default from the current look and feel.
377 * @param title the title text, or <code>null</code> to use no title
378 * text.
380 * @param titleJustification the horizontal alignment of the title
381 * text in relation to the border. The value must be one of
382 * {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, {@link #LEADING},
383 * {@link #TRAILING}, or {@link #DEFAULT_JUSTIFICATION}.
385 * @param titlePosition the vertical position of the title text
386 * in relation to the border. The value must be one of
387 * {@link #ABOVE_TOP}, {@link #TOP}, {@link #BELOW_TOP},
388 * {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link #BELOW_BOTTOM},
389 * or {@link #DEFAULT_POSITION}.
391 * @param titleFont the font for the title text, or <code>null</code>
392 * to use a default from the current look and feel.
394 * @throws IllegalArgumentException if <code>titleJustification</code>
395 * or <code>titlePosition</code> have an unsupported value.
397 public TitledBorder(Border border, String title, int titleJustification,
398 int titlePosition, Font titleFont)
400 this(border, title, titleJustification, titlePosition, titleFont,
401 /* titleColor */ null);
406 * Constructs a TitledBorder given its border, title text, horizontal
407 * alignment, vertical position, font, and color.
409 * @param border the border underneath the title, or <code>null</code>
410 * to use a default from the current look and feel.
412 * @param title the title text, or <code>null</code> to use no title
413 * text.
415 * @param titleJustification the horizontal alignment of the title
416 * text in relation to the border. The value must be one of
417 * {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, {@link #LEADING},
418 * {@link #TRAILING}, or {@link #DEFAULT_JUSTIFICATION}.
420 * @param titlePosition the vertical position of the title text
421 * in relation to the border. The value must be one of
422 * {@link #ABOVE_TOP}, {@link #TOP}, {@link #BELOW_TOP},
423 * {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link #BELOW_BOTTOM},
424 * or {@link #DEFAULT_POSITION}.
426 * @param titleFont the font for the title text, or <code>null</code>
427 * to use a default from the current look and feel.
429 * @param titleColor the color for the title text, or <code>null</code>
430 * to use a default from the current look and feel.
432 * @throws IllegalArgumentException if <code>titleJustification</code>
433 * or <code>titlePosition</code> have an unsupported value.
435 public TitledBorder(Border border, String title, int titleJustification,
436 int titlePosition, Font titleFont, Color titleColor)
438 this.border = border;
439 this.title = title;
441 /* Invoking the setter methods ensures that the newly constructed
442 * TitledBorder has valid property values.
444 setTitleJustification(titleJustification);
445 setTitlePosition(titlePosition);
447 this.titleFont = titleFont;
448 this.titleColor = titleColor;
453 * Paints the border and the title text.
455 * @param c the component whose border is to be painted.
456 * @param g the graphics for painting.
457 * @param x the horizontal position for painting the border.
458 * @param y the vertical position for painting the border.
459 * @param width the width of the available area for painting the border.
460 * @param height the height of the available area for painting the border.
462 public void paintBorder(Component c, Graphics g,
463 int x, int y, int width, int height)
465 Measurements mes = getMeasurements(c);
466 Font oldFont = g.getFont();
467 Color oldColor = g.getColor();
470 * A local helper class for painting the border without changing
471 * any pixels inside the rectangle of the title text.
473 class BorderPainter
475 private Component c;
476 private Border b;
477 private int x, y, width, height;
480 * Constructs a BorderPainter.
482 * @param c the component whose border is being painted.
483 * @param b the border object.
484 * @param x the x coordinate of the rectangle delimiting the border.
485 * @param y the y coordinate of the rectangle delimiting the border.
486 * @param width the width of the rectangle delimiting the border.
487 * @param height the width of the rectangle delimiting the border.
489 public BorderPainter(Component c, Border b,
490 int x, int y, int width, int height)
492 this.c = c;
493 this.b = b;
494 this.x = x;
495 this.y = y;
496 this.width = width;
497 this.height = height;
502 * Paints the entire border.
504 public void paint(Graphics g)
506 if (b != null)
507 b.paintBorder(c, g, x, y, width - 1, height - 1);
512 * Paints the border, clipping the drawing operation to a
513 * given rectangular area.
515 private void paint(Graphics g,
516 int clipX, int clipY, int clipWidth, int clipHeight)
518 Shape oldClip = g.getClip();
521 g.clipRect(clipX, clipY, clipWidth, clipHeight);
522 paint(g);
524 finally
526 g.setClip(oldClip);
532 * Paints the border without affecting a given rectangular area.
533 * This is used for painting the border without drawing anything
534 * underneath the title text.
536 * <p>Since we do not want to introduce unnecessary dependencies
537 * on Java 2D, we perform the clipping without constructive geometry
538 * (provided by java.awt.geom.Area). Instead, the border&#x2019;s
539 * bounding rectangle is split into smaller parts, which are then
540 * clipped and painted individually.:
542 * <p><pre>
543 * +--------------------+ +--------------------+
544 * | | | 1 |
545 * | +--------+ | +---+--------+-------+
546 * | | hole | | |====> | 2 | hole | 3 |
547 * | +--------+ | |---+--------+-------+
548 * | | | 4 |
549 * +--------------------+ +--------------------+</pre>
552 public void paintExcept(Graphics g,
553 int holeX, int holeY, int holeWidth, int holeHeight)
555 int stripeHeight;
557 stripeHeight = holeY - y;
558 if (stripeHeight > 0)
559 paint(g, x, y, width, stripeHeight); // patch #1 in the image above
561 stripeHeight = holeHeight;
562 if (stripeHeight > 0)
564 paint(g, x, holeY, holeX - x, stripeHeight); // patches #2 and #3
565 paint(g, holeX + holeWidth, holeY, width - (holeX + holeWidth), stripeHeight);
568 stripeHeight = height - (holeY - y + holeHeight);
569 if (stripeHeight > 0)
570 paint(g, x, y + height - stripeHeight, width, stripeHeight); // #4
574 BorderPainter bp;
575 int textX, textY, borderWidth, borderHeight;
577 borderWidth = width - (mes.borderSpacing.left + mes.borderSpacing.right);
578 borderHeight = height - (mes.borderSpacing.top + mes.borderSpacing.bottom);
579 bp = new BorderPainter(c, getBorder(),
580 x + mes.borderSpacing.left, y + mes.borderSpacing.top,
581 borderWidth, borderHeight);
583 switch (getRealTitleJustification(c))
585 case LEFT:
586 textX = x + TEXT_INSET_H;
587 break;
589 case CENTER:
590 textX = x + (borderWidth - mes.textWidth) / 2;
591 break;
593 case RIGHT:
594 textX = x + borderWidth - (mes.textWidth + TEXT_INSET_H);
595 break;
597 default:
598 throw new IllegalStateException();
601 switch (titlePosition)
603 case ABOVE_TOP:
604 textY = y;
605 break;
607 case TOP:
608 case DEFAULT_POSITION:
609 default:
610 textY = y + mes.borderSpacing.top + mes.borderInsets.top - mes.textAscent;
611 break;
613 case BELOW_TOP:
614 textY = y + mes.borderSpacing.top + mes.borderInsets.top + TEXT_SPACING;
615 break;
617 case ABOVE_BOTTOM:
618 textY = y + height - mes.borderSpacing.bottom - mes.borderInsets.bottom
619 - TEXT_SPACING - (mes.textAscent + mes.textDescent);
620 break;
622 case BOTTOM:
623 case BELOW_BOTTOM:
624 textY = y + height - (mes.textAscent + mes.textDescent);
625 break;
628 if (mes.trimmedText == null)
629 bp.paint(g);
630 else
634 g.setFont(mes.font);
635 g.setColor(getTitleColor());
636 g.drawString(mes.trimmedText, textX, textY + mes.textAscent);
638 finally
640 g.setFont(oldFont);
641 g.setColor(oldColor);
643 bp.paintExcept(g, textX - 2, textY,
644 mes.textWidth + 2, mes.textAscent + mes.textDescent);
650 * Measures the width of this border.
652 * @param c the component whose border is to be measured.
654 * @return an Insets object whose <code>left</code>, <code>right</code>,
655 * <code>top</code> and <code>bottom</code> fields indicate the
656 * width of the border at the respective edge.
658 * @see #getBorderInsets(java.awt.Component, java.awt.Insets)
660 public Insets getBorderInsets(Component c)
662 return getBorderInsets(c, new Insets(0, 0, 0, 0));
667 * Measures the width of this border, storing the results into a
668 * pre-existing Insets object.
670 * @param insets an Insets object for holding the result values.
671 * After invoking this method, the <code>left</code>,
672 * <code>right</code>, <code>top</code> and
673 * <code>bottom</code> fields indicate the width of the
674 * border at the respective edge.
676 * @return the same object that was passed for <code>insets</code>.
678 * @see #getBorderInsets()
680 public Insets getBorderInsets(Component c, Insets insets)
682 return getMeasurements(c).getContentInsets(insets);
687 * Returns <code>false</code>, indicating that there are pixels inside
688 * the area of this border where the background shines through.
690 * @return <code>false</code>.
692 public boolean isBorderOpaque()
694 /* Note that the AbstractBorder.isBorderOpaque would also return
695 * false, so there is actually no need to override the inherited
696 * implementation. However, GNU Classpath strives for exact
697 * compatibility with the Sun reference implementation, which
698 * overrides isBorderOpaque for unknown reasons.
700 return false;
705 * Returns the text of the title.
707 * @return the title text, or <code>null</code> if no title is
708 * displayed.
710 public String getTitle()
712 return title;
717 * Retrieves the border underneath the title. If no border has been
718 * set, or if it has been set to<code>null</code>, the current
719 * {@link javax.swing.LookAndFeel} will be asked for a border
720 * using the key <code>&quot;TitledBorder.border&quot;</code>.
722 * @return a border, or <code>null</code> if the current LookAndFeel
723 * does not provide a border for the key
724 * <code>&quot;TitledBorder.border&quot;</code>.
726 * @see javax.swing.UIManager#getBorder(Object)
728 public Border getBorder()
730 if (border != null)
731 return border;
733 return UIManager.getBorder("TitledBorder.border");
738 * Returns the vertical position of the title text in relation
739 * to the border.
741 * @return one of the values {@link #ABOVE_TOP}, {@link #TOP},
742 * {@link #BELOW_TOP}, {@link #ABOVE_BOTTOM}, {@link #BOTTOM},
743 * {@link #BELOW_BOTTOM}, or {@link #DEFAULT_POSITION}.
745 public int getTitlePosition()
747 return titlePosition;
752 * Returns the horizontal alignment of the title text in relation to
753 * the border.
755 * @return one of the values {@link #LEFT}, {@link #CENTER}, {@link
756 * #RIGHT}, {@link #LEADING}, {@link #TRAILING}, or {@link
757 * #DEFAULT_JUSTIFICATION}.
759 public int getTitleJustification()
761 return titleJustification;
766 * Retrieves the font for displaying the title text. If no font has
767 * been set, or if it has been set to<code>null</code>, the current
768 * {@link javax.swing.LookAndFeel} will be asked for a font
769 * using the key <code>&quot;TitledBorder.font&quot;</code>.
771 * @return a font, or <code>null</code> if the current LookAndFeel
772 * does not provide a font for the key
773 * <code>&quot;TitledBorder.font&quot;</code>.
775 * @see javax.swing.UIManager#getFont(Object)
777 public Font getTitleFont()
779 if (titleFont != null)
780 return titleFont;
782 return UIManager.getFont("TitledBorder.font");
787 * Retrieves the color for displaying the title text. If no color has
788 * been set, or if it has been set to<code>null</code>, the current
789 * {@link javax.swing.LookAndFeel} will be asked for a color
790 * using the key <code>&quot;TitledBorder.titleColor&quot;</code>.
792 * @return a color, or <code>null</code> if the current LookAndFeel
793 * does not provide a color for the key
794 * <code>&quot;TitledBorder.titleColor&quot;</code>.
796 * @see javax.swing.UIManager#getColor(Object)
798 public Color getTitleColor()
800 if (titleColor != null)
801 return titleColor;
803 return UIManager.getColor("TitledBorder.titleColor");
808 * Sets the text of the title.
810 * @param title the new title text, or <code>null</code> for displaying
811 * no text at all.
813 public void setTitle(String title)
815 // Swing borders are not JavaBeans, thus no need to fire an event.
816 this.title = title;
821 * Sets the border underneath the title.
823 * @param border a border, or <code>null</code> to use the
824 * border that is supplied by the current LookAndFeel.
826 * @see #getBorder()
828 public void setBorder(Border border)
830 // Swing borders are not JavaBeans, thus no need to fire an event.
831 this.border = border;
836 * Sets the vertical position of the title text in relation
837 * to the border.
839 * @param titlePosition one of the values {@link #ABOVE_TOP},
840 * {@link #TOP}, {@link #BELOW_TOP}, {@link #ABOVE_BOTTOM},
841 * {@link #BOTTOM}, {@link #BELOW_BOTTOM},
842 * or {@link #DEFAULT_POSITION}.
844 * @throws IllegalArgumentException if an unsupported value is passed
845 * for <code>titlePosition</code>.
847 public void setTitlePosition(int titlePosition)
849 if ((titlePosition < DEFAULT_POSITION) || (titlePosition > BELOW_BOTTOM))
850 throw new IllegalArgumentException();
852 // Swing borders are not JavaBeans, thus no need to fire an event.
853 this.titlePosition = titlePosition;
858 * Sets the horizontal alignment of the title text in relation to the border.
860 * @param titleJustification the new alignment, which must be one of
861 * {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, {@link #LEADING},
862 * {@link #TRAILING}, or {@link #DEFAULT_JUSTIFICATION}.
864 * @throws IllegalArgumentException if an unsupported value is passed
865 * for <code>titleJustification</code>.
867 public void setTitleJustification(int titleJustification)
869 if ((titleJustification < DEFAULT_JUSTIFICATION)
870 || (titleJustification > TRAILING))
871 throw new IllegalArgumentException();
873 // Swing borders are not JavaBeans, thus no need to fire an event.
874 this.titleJustification = titleJustification;
879 * Sets the font for displaying the title text.
881 * @param titleFont the font, or <code>null</code> to use the font
882 * provided by the current {@link javax.swing.LookAndFeel}.
884 * @see #getTitleFont()
886 public void setTitleFont(Font titleFont)
888 // Swing borders are not JavaBeans, thus no need to fire an event.
889 this.titleFont = titleFont;
894 * Sets the color for displaying the title text.
896 * @param titleColor the color, or <code>null</code> to use the color
897 * provided by the current {@link javax.swing.LookAndFeel}.
899 * @see #getTitleColor()
901 public void setTitleColor(Color titleColor)
903 // Swing borders are not JavaBeans, thus no need to fire an event.
904 this.titleColor = titleColor;
909 * Calculates the minimum size needed for displaying the border
910 * and its title.
912 * @param c the Component for which this TitledBorder consitutes
913 * a border.
915 public Dimension getMinimumSize(Component c)
917 return getMeasurements(c).getMinimumSize();
922 * Returns the font that is used for displaying the title text for
923 * a given Component.
925 * @param c the Component for which this TitledBorder is the border.
927 * @return The font returned by {@link #getTitleFont()}, or a fallback
928 * if {@link #getTitleFont()} returned <code>null</code>.
930 protected Font getFont(Component c)
932 Font f;
934 f = getTitleFont();
935 if (f != null)
936 return f;
938 return new Font("Dialog", Font.PLAIN, 12);
943 * Returns the horizontal alignment of the title text in relation to
944 * the border, mapping the component-dependent alignment constants
945 * {@link #LEADING}, {@link #TRAILING} and {@link #DEFAULT_JUSTIFICATION}
946 * to the correct value according to the embedded component&#x2019;s
947 * orientation.
949 * @param c the Component for which this TitledBorder is the border.
951 * @return one of the values {@link #LEFT}, {@link #CENTER}, or {@link
952 * #RIGHT}.
954 private int getRealTitleJustification(Component c)
956 switch (titleJustification)
958 case DEFAULT_JUSTIFICATION:
959 case LEADING:
960 if ((c == null) || c.getComponentOrientation().isLeftToRight())
961 return LEFT;
962 else
963 return RIGHT;
965 case TRAILING:
966 if ((c == null) || c.getComponentOrientation().isLeftToRight())
967 return RIGHT;
968 else
969 return LEFT;
971 default:
972 return titleJustification;
978 * Performs various measurements for the current state of this TitledBorder
979 * and the given Component.
981 private Measurements getMeasurements(Component c)
983 Measurements m = new Measurements();
984 FontMetrics fmet;
986 m.font = getFont(c);
987 fmet = c.getFontMetrics(m.font);
988 m.border = getBorder();
989 if (m.border != null)
990 m.borderInsets = m.border.getBorderInsets(c);
991 else
992 m.borderInsets = new Insets(0, 0, 0, 0);
994 if (title != null)
996 m.trimmedText = title.trim();
997 if (m.trimmedText.length() == 0)
998 m.trimmedText = null;
1001 m.textAscent = fmet.getAscent();
1002 m.textDescent = fmet.getDescent();
1003 if (m.trimmedText != null)
1004 m.textWidth = fmet.stringWidth(m.trimmedText) + 3;
1006 m.edgeSpacing = new Insets(EDGE_SPACING, EDGE_SPACING, EDGE_SPACING, EDGE_SPACING);
1007 m.borderSpacing = new Insets(0, 0, 0, 0);
1009 switch (titlePosition)
1011 case ABOVE_TOP:
1012 m.borderSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING;
1013 break;
1015 case BELOW_TOP:
1016 m.edgeSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING;
1017 break;
1019 case ABOVE_BOTTOM:
1020 m.edgeSpacing.bottom += m.textAscent + m.textDescent + TEXT_SPACING;
1021 break;
1023 case BOTTOM:
1024 m.edgeSpacing.bottom += Math.max(m.textAscent - m.borderInsets.bottom, 0);
1025 m.borderSpacing.bottom += m.textDescent;
1026 break;
1028 case BELOW_BOTTOM:
1029 m.borderSpacing.bottom += m.textAscent + m.textDescent + TEXT_SPACING;
1030 break;
1032 default:
1033 m.borderSpacing.top += m.textAscent;
1036 return m;
1041 * A private helper class for holding the result of measuring the
1042 * distances of a TitledBorder. While it would be possible to cache
1043 * these objects, it does not seem to be worth the effort. Note that
1044 * invalidating the cache would be tricky, especially since there is
1045 * no notification mechanism that would inform the cache when
1046 * border has changed, so it would return different insets.
1048 private static class Measurements
1051 * The font used for displaying the title text. Note that it can
1052 * well be that the TitledBorder&#x2019;s font is <code>null</code>,
1053 * which means that the font is to be retrieved from the current
1054 * LookAndFeel. In this case, this <code>font</code> field will
1055 * contain the result of the retrieval. Therefore, it is safe
1056 * to assume that his <code>font</code> field will never have
1057 * a <code>null</code> value.
1059 Font font;
1063 * The number of pixels between the base line and the top of the
1064 * text box.
1066 int textAscent;
1070 * The number of pixels between the base line and the bottom of
1071 * the text box.
1073 int textDescent;
1077 * The title text after removing leading and trailing white space
1078 * characters. If the title consists only of white space, the
1079 * value of <code>trimmedText</code> will be <code>null</code>.
1081 String trimmedText;
1085 * The width of the trimmed title text in pixels.
1087 int textWidth;
1091 * The border that constitues the &quot;interior&quot; border
1092 * underneath the title text.
1094 Border border;
1098 * The distance between the TitledBorder and the interior border.
1100 Insets borderSpacing;
1104 * The width of the interior border, as returned by
1105 * <code>border.getBorderInsets()</code>.
1107 Insets borderInsets;
1111 * The distance between the interior border and the nested
1112 * Component for which this TitledBorder is a border.
1114 Insets edgeSpacing;
1118 * Determines the insets of the nested component when it has a
1119 * TitledBorder as its border. Used by {@link
1120 * TitledBorder#getBorderInsets()}.
1122 * @param i an Insets object for storing the results into, or
1123 * <code>null</code> to cause the creation of a
1124 * new instance.
1126 * @return the <code>i</code> object, or a new Insets object
1127 * if <code>null</code> was passed for <code>i</code>.
1129 public Insets getContentInsets(Insets i)
1131 if (i == null)
1132 i = new Insets(0, 0, 0, 0);
1133 i.left = borderSpacing.left + borderInsets.left + edgeSpacing.left;
1134 i.right = borderSpacing.right + borderInsets.right + edgeSpacing.right;
1135 i.top = borderSpacing.top + borderInsets.top + edgeSpacing.top;
1136 i.bottom = borderSpacing.bottom + borderInsets.bottom + edgeSpacing.bottom;
1137 return i;
1142 * Calculates the minimum size needed for displaying the border
1143 * and its title. Used by {@link TitledBorder#getMiminumSize()}.
1145 public Dimension getMinimumSize()
1147 int width;
1148 Insets insets;
1150 insets = getContentInsets(null);
1151 width = Math.max(insets.left + insets.right, textWidth + 2 * TEXT_INSET_H);
1152 return new Dimension(width, insets.top + insets.bottom);