2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / javax / swing / plaf / basic / BasicBorders.java
blob7002d14332c21a0d32c82531d7b4a605880effa4
1 /* BasicBorders.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.plaf.basic;
41 import java.awt.Color;
42 import java.awt.Component;
43 import java.awt.Graphics;
44 import java.awt.Insets;
45 import java.awt.Rectangle;
46 import java.io.Serializable;
47 import javax.swing.AbstractButton;
48 import javax.swing.ButtonModel;
49 import javax.swing.JButton;
50 import javax.swing.JPopupMenu;
51 import javax.swing.JSplitPane;
52 import javax.swing.JToolBar;
53 import javax.swing.UIDefaults;
54 import javax.swing.UIManager;
55 import javax.swing.border.AbstractBorder;
56 import javax.swing.border.BevelBorder;
57 import javax.swing.border.Border;
58 import javax.swing.plaf.UIResource;
59 import javax.swing.plaf.BorderUIResource;
60 import javax.swing.text.JTextComponent;
63 /**
64 * Provides various borders for the Basic look and feel.
66 * @author Sascha Brawer (brawer@dandelis.ch)
68 public class BasicBorders
70 /**
71 * A MarginBorder that gets shared by multiple components.
72 * Created on demand by the private helper function {@link
73 * #getMarginBorder()}.
75 private static MarginBorder sharedMarginBorder;
78 /**
79 * Returns a border for drawing push buttons.
81 * <p>The colors of the border are retrieved from the
82 * <code>UIDefaults</code> of the currently active look and feel
83 * using the keys <code>&#x201c;Button.shadow&#x201d;</code>,
84 * <code>&#x201c;Button.darkShadow&#x201d;</code>,
85 * <code>&#x201c;Button.light&#x201d;</code>, and
86 * <code>&#x201c;Button.highlight&#x201d;</code>.
88 * <p><img src="doc-files/BasicBorders.ButtonBorder-1.png" width="300"
89 * height="170" alt="[A screen shot of the returned border]" />
91 * @return a {@link
92 * javax.swing.plaf.BorderUIResource#CompoundBorderUIResource}
93 * whose outer border is a {@link #ButtonBorder} and whose
94 * inner border is a {@link #MarginBorder}.
96 public static Border getButtonBorder()
98 UIDefaults defaults;
99 Border outer;
101 defaults = UIManager.getLookAndFeelDefaults();
103 /* The keys for UIDefaults have been determined by writing a
104 * test program that dumps the UIDefaults to stdout; that program
105 * was run on a JDK 1.4.1_01 for GNU/Linux. Note that in the API,
106 * the key "light" is usually called "highlight", and "highlight"
107 * is usually called "lightHighlight".
109 outer = new ButtonBorder(defaults.getColor("Button.shadow"),
110 defaults.getColor("Button.darkShadow"),
111 defaults.getColor("Button.light"),
112 defaults.getColor("Button.highlight"));
114 /* While the inner border is shared between multiple buttons,
115 * we do not share the outer border because ButtonBorders store
116 * their border colors. We cannot guarantee that the colors
117 * (which come from UIDefaults) are unchanged between invocations
118 * of getButtonBorder. We could store the last colors, and share
119 * the button border if the colors are the same as in the last
120 * invocation, but it probably is not worth the effort.
122 return new BorderUIResource.CompoundBorderUIResource(
123 outer,
124 /* inner */ getMarginBorder());
129 * Returns a border for drawing radio buttons.
131 * <p>The colors of the border are retrieved from the
132 * <code>UIDefaults</code> of the currently active look and feel
133 * using the keys <code>&#x201c;RadioButton.shadow&#x201d;</code>,
134 * <code>&#x201c;RadioButton.darkShadow&#x201d;</code>,
135 * <code>&#x201c;RadioButton.light&#x201d;</code>, and
136 * <code>&#x201c;RadioButton.highlight&#x201d;</code>.
138 * <p><img src="doc-files/BasicBorders.RadioButtonBorder-1.png" width="300"
139 * height="135" alt="[A screen shot of the returned border]" />
141 * @return a {@link
142 * javax.swing.plaf.BorderUIResource#CompoundBorderUIResource}
143 * whose outer border is a {@link #RadioButtonBorder} and whose
144 * inner border is a {@link #MarginBorder}.
146 public static Border getRadioButtonBorder()
148 UIDefaults defaults;
149 Border outer;
151 defaults = UIManager.getLookAndFeelDefaults();
153 /* The keys for UIDefaults have been determined by writing a
154 * test program that dumps the UIDefaults to stdout; that program
155 * was run on a JDK 1.4.1_01 for GNU/Linux. Note that in the API,
156 * the key "light" is usually called "highlight", and "highlight"
157 * is usually called "lightHighlight".
159 outer = new RadioButtonBorder(
160 defaults.getColor("RadioButton.shadow"),
161 defaults.getColor("RadioButton.darkShadow"),
162 defaults.getColor("RadioButton.light"),
163 defaults.getColor("RadioButton.highlight"));
165 /* While the inner border is shared between multiple buttons, we
166 * do not share the outer border because RadioButtonBorders, being
167 * ButtonBorders, store their border colors. We cannot guarantee
168 * that the colors (which come from UIDefaults) are unchanged
169 * between invocations of getButtonBorder. We could store the last
170 * colors, and share the button border if the colors are the same
171 * as in the last invocation, but it probably is not worth the
172 * effort.
174 return new BorderUIResource.CompoundBorderUIResource(
175 outer,
176 /* inner */ getMarginBorder());
181 * Returns a border for drawing toggle buttons.
183 * <p>The colors of the border are retrieved from the
184 * <code>UIDefaults</code> of the currently active look and feel
185 * using the keys <code>&#x201c;ToggleButton.shadow&#x201d;</code>,
186 * <code>&#x201c;ToggleButton.darkShadow&#x201d;</code>,
187 * <code>&#x201c;ToggleButton.light&#x201d;</code>, and
188 * <code>&#x201c;ToggleButton.highlight&#x201d;</code>.
190 * <p><img src="doc-files/BasicBorders.ToggleButtonBorder-1.png" width="270"
191 * height="135" alt="[A screen shot of the returned border]" />
193 * @return a {@link
194 * javax.swing.plaf.BorderUIResource#CompoundBorderUIResource}
195 * whose outer border is a {@link #ToggleButtonBorder} and whose
196 * inner border is a {@link #MarginBorder}.
198 public static Border getToggleButtonBorder()
200 UIDefaults defaults;
201 Border outer;
203 defaults = UIManager.getLookAndFeelDefaults();
205 /* The keys for UIDefaults have been determined by writing a
206 * test program that dumps the UIDefaults to stdout; that program
207 * was run on a JDK 1.4.1_01 for GNU/Linux. Note that in the API,
208 * the key "light" is usually called "highlight", and "highlight"
209 * is usually called "lightHighlight".
211 outer = new ToggleButtonBorder(
212 defaults.getColor("ToggleButton.shadow"),
213 defaults.getColor("ToggleButton.darkShadow"),
214 defaults.getColor("ToggleButton.light"),
215 defaults.getColor("ToggleButton.highlight"));
217 /* While the inner border is shared between multiple buttons, we
218 * do not share the outer border because ToggleButtonBorders, being
219 * ButtonBorders, store their border colors. We cannot guarantee
220 * that the colors (which come from UIDefaults) are unchanged
221 * between invocations of getButtonBorder. We could store the last
222 * colors, and share the button border if the colors are the same
223 * as in the last invocation, but it probably is not worth the
224 * effort.
226 return new BorderUIResource.CompoundBorderUIResource(
227 outer,
228 /* inner */ getMarginBorder());
233 * Returns a border for drawing a two-pixel thick separator line
234 * below menu bars.
236 * <p>The colors of the border are retrieved from the
237 * <code>UIDefaults</code> of the currently active look and feel
238 * using the keys <code>&#x201c;MenuBar.shadow&#x201d;</code> and
239 * <code>&#x201c;MenuBar.highlight&#x201d;</code>.
241 * <p><img src="doc-files/BasicBorders.MenuBarBorder-1.png" width="500"
242 * height="140" alt="[A screen shot of a JMenuBar with this border]" />
244 * @return a {@link #MenuBarBorder}.
246 * @see javax.swing.JMenuBar
248 public static Border getMenuBarBorder()
250 UIDefaults defaults;
252 /* See comment in methods above for why this border is not shared. */
253 defaults = UIManager.getLookAndFeelDefaults();
254 return new MenuBarBorder(defaults.getColor("MenuBar.shadow"),
255 defaults.getColor("MenuBar.highlight"));
260 * Returns a border for drawing a one-pixel thick border around
261 * split panes that are interrupted where the divider joins the
262 * border.
264 * <p>The colors of the border are retrieved from the
265 * <code>UIDefaults</code> of the currently active look and feel
266 * using the keys <code>&#x201c;SplitPane.darkShadow&#x201d;</code> and
267 * <code>&#x201c;SplitPane.highlight&#x201d;</code>.
269 * <p><img src="doc-files/BasicBorders.SplitPaneBorder-1.png" width="520"
270 * height="200" alt="[A screen shot for JSplitPane.HORIZONTAL_SPLIT]" />
272 * <p><img src="doc-files/BasicBorders.SplitPaneBorder-2.png" width="520"
273 * height="200" alt="[A screen shot for JSplitPane.VERTICAL_SPLIT]" />
275 * @return a {@link #SplitPaneBorder}.
277 * @see javax.swing.JSplitPane
278 * @see #getSplitPaneDividerBorder()
280 public static Border getSplitPaneBorder()
282 UIDefaults defaults;
284 /* See comment in methods above for why this border is not shared. */
285 defaults = UIManager.getLookAndFeelDefaults();
286 return new SplitPaneBorder(defaults.getColor("SplitPane.highlight"),
287 defaults.getColor("SplitPane.darkShadow"));
292 * Returns a border for drawing a one-pixel thick border around
293 * the divider of split panes.
295 * <p>The colors of the edges that are adjacent to the child components
296 * of the <code>JSplitPane</code> are retrieved from the
297 * <code>UIDefaults</code> of the currently active look and feel
298 * using the keys <code>&#x201c;SplitPane.darkShadow&#x201d;</code> and
299 * <code>&#x201c;SplitPane.highlight&#x201d;</code>. The color of the
300 * other two edges is the background color of the divider.
302 * <p><img src="doc-files/BasicBorders.SplitPaneDividerBorder-1.png"
303 * width="520" height="200" alt=
304 * "[A screen shot for JSplitPane.HORIZONTAL_SPLIT]" />
306 * @return an instance of <code>SplitPaneDividerBorder</code>, which is
307 * not a public API class of this package.
309 * @see javax.swing.JSplitPane
310 * @see javax.swing.plaf.basic.BasicSplitPaneDivider
311 * @see #getSplitPaneBorder()
313 * @since 1.3
315 public static Border getSplitPaneDividerBorder()
317 UIDefaults defaults;
319 /* See comment in methods above for why this border is not shared. */
320 defaults = UIManager.getLookAndFeelDefaults();
321 return new SplitPaneDividerBorder(
322 defaults.getColor("SplitPane.highlight"),
323 defaults.getColor("SplitPane.darkShadow"));
328 * Returns a border for drawing a border around a text field
329 * that makes the field appear as etched into the surface.
331 * <p>The colors of the border are retrieved from the
332 * <code>UIDefaults</code> of the currently active look and feel
333 * using the keys <code>&#x201c;TextField.shadow&#x201d;</code>,
334 * <code>&#x201c;TextField.darkShadow&#x201d;</code>,
335 * <code>&#x201c;TextField.light&#x201d;</code>, and
336 * <code>&#x201c;TextField.highlight&#x201d;</code>.
338 * <p><img src="doc-files/BasicBorders.FieldBorder-1.png" width="500"
339 * height="200" alt="[A screen shot of a border returned by
340 * this method]" />
342 * @return an instance of
343 * {@link javax.swing.plaf.basic.BasicBorders$FieldBorder}.
345 * @see javax.swing.JTextField
346 * @see javax.swing.text.JTextComponent
348 public static Border getTextFieldBorder()
350 UIDefaults defaults;
352 /* See comment in methods above for why this border is not shared. */
353 defaults = UIManager.getLookAndFeelDefaults();
354 return new FieldBorder(
355 defaults.getColor("TextField.shadow"),
356 defaults.getColor("TextField.darkShadow"),
357 defaults.getColor("TextField.light"),
358 defaults.getColor("TextField.highlight"));
363 * Returns a two-pixel thick, green
364 * <code>LineBorderUIResource</code>. This is so ugly that look and
365 * feels better use different borders for their progress bars, or
366 * they will look really terrible.
368 * <p><img src="doc-files/BasicBorders-1.png" width="120" height="80"
369 * alt="[A screen shot of a border returned by this method]" />
371 public static Border getProgressBarBorder()
373 /* There does not seem to exist a way to parametrize the color
374 * or thickness of the border through UIDefaults.
376 return new BorderUIResource.LineBorderUIResource(Color.green, 2);
381 * Returns a border that is composed of a raised bevel border and a
382 * one-pixel thick line border.
384 * <p><img src="doc-files/BasicBorders-2.png" width="300" height="200"
385 * alt="[A screen shot of a border returned by this method]" />
387 * <p>The colors of the border are retrieved from the
388 * <code>UIDefaults</code> of the currently active look and feel
389 * using the keys <code>&#x201c;InternalFrame.borderShadow&#x201d;</code>,
390 * <code>&#x201c;InternalFrame.borderDarkShadow&#x201d;</code>,
391 * <code>&#x201c;InternalFrame.borderLight&#x201d;</code>,
392 * <code>&#x201c;InternalFrame.borderHighlight&#x201d;</code>, and
393 * (for the inner one-pixel thick line)
394 * <code>&#x201c;InternalFrame.borderColor&#x201d;</code>.
396 public static Border getInternalFrameBorder()
398 UIDefaults defaults;
399 Color shadow, darkShadow, highlight, lightHighlight, line;
401 /* See comment in methods above for why this border is not shared. */
402 defaults = UIManager.getLookAndFeelDefaults();
404 shadow = defaults.getColor("InternalFrame.borderShadow");
405 darkShadow = defaults.getColor("InternalFrame.borderDarkShadow");
406 highlight = defaults.getColor("InternalFrame.borderLight");
407 lightHighlight = defaults.getColor("InternalFrame.borderHighlight");
408 line = defaults.getColor("InternalFrame.borderColor");
410 return new BorderUIResource.CompoundBorderUIResource(
411 /* outer border */
412 new BorderUIResource.BevelBorderUIResource(
413 BevelBorder.RAISED,
414 (highlight != null) ? highlight : Color.lightGray,
415 (lightHighlight != null) ? lightHighlight : Color.white,
416 (darkShadow != null) ? darkShadow : Color.black,
417 (shadow != null) ? shadow : Color.gray),
419 /* inner border */
420 new BorderUIResource.LineBorderUIResource(
421 (line != null) ? line : Color.lightGray));
426 * Returns a shared MarginBorder.
428 static Border getMarginBorder() // intentionally not public
430 /* Swing is not designed to be thread-safe, so there is no
431 * need to synchronize the access to the global variable.
433 if (sharedMarginBorder == null)
434 sharedMarginBorder = new MarginBorder();
436 return sharedMarginBorder;
441 * A border whose appearance depends on the state of
442 * the enclosed button.
444 * <p><img src="doc-files/BasicBorders.ButtonBorder-1.png" width="300"
445 * height="170" alt="[A screen shot of this border]" />
447 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
449 * @author Sascha Brawer (brawer@dandelis.ch)
451 public static class ButtonBorder
452 extends AbstractBorder
453 implements Serializable, UIResource
456 * Determined using the <code>serialver</code> tool
457 * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
459 static final long serialVersionUID = -157053874580739687L;
463 * The color for drawing the shaded parts of the border.
464 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
466 protected Color shadow;
470 * The color for drawing the dark shaded parts of the border.
471 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
473 protected Color darkShadow;
477 * The color for drawing the highlighted parts of the border.
478 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
480 protected Color highlight;
484 * The color for drawing the bright highlighted parts of the border.
485 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
487 protected Color lightHighlight;
491 * Constructs a new border for drawing a button in the Basic
492 * look and feel.
494 * @param shadow the shadow color.
495 * @param darkShadow a darker variant of the shadow color.
496 * @param highlight the highlight color.
497 * @param lightHighlight a brighter variant of the highlight color.
499 public ButtonBorder(Color shadow, Color darkShadow,
500 Color highlight, Color lightHighlight)
502 /* These colors usually come from the UIDefaults of the current
503 * look and feel. Use fallback values if the colors are not
504 * supplied. The API specification is silent about what
505 * behavior is expected for null colors, so users should not
506 * rely on this fallback (which is why it is not documented in
507 * the above Javadoc).
509 this.shadow = (shadow != null) ? shadow : Color.gray;
510 this.darkShadow = (darkShadow != null) ? darkShadow : Color.black;
511 this.highlight = (highlight != null) ? highlight : Color.lightGray;
512 this.lightHighlight = (lightHighlight != null)
513 ? lightHighlight
514 : Color.white;
519 * Paints the ButtonBorder around a given component.
521 * @param c the component whose border is to be painted.
522 * @param g the graphics for painting.
523 * @param x the horizontal position for painting the border.
524 * @param y the vertical position for painting the border.
525 * @param width the width of the available area for painting the border.
526 * @param height the height of the available area for painting the border.
528 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
530 public void paintBorder(Component c, Graphics g,
531 int x, int y, int width, int height)
533 ButtonModel bmodel = null;
535 if (c instanceof AbstractButton)
536 bmodel = ((AbstractButton) c).getModel();
538 BasicGraphicsUtils.drawBezel(
539 g, x, y, width, height,
540 /* pressed */ (bmodel != null)
541 && /* mouse button pressed */ bmodel.isPressed()
542 && /* mouse inside */ bmodel.isArmed(),
543 /* default */ (c instanceof JButton)
544 && ((JButton) c).isDefaultButton(),
545 shadow, darkShadow, highlight, lightHighlight);
550 * Measures the width of this border.
552 * <p>Although the thickness of the actually painted border
553 * depends on the state of the enclosed component, this
554 * measurement always returns the same amount of pixels. Indeed,
555 * it would be rather confusing if a button was appearing to
556 * change its size depending on whether it is pressed or not.
558 * @param c the component whose border is to be measured.
560 * @return an Insets object whose <code>left</code>,
561 * <code>right</code>, <code>top</code> and
562 * <code>bottom</code> fields indicate the width of the
563 * border at the respective edge.
565 * @see #getBorderInsets(java.awt.Component, java.awt.Insets)
567 public Insets getBorderInsets(Component c)
569 /* There is no obvious reason for overriding this method, but we
570 * try to have exactly the same API as the Sun reference
571 * implementation.
573 return getBorderInsets(c, null);
578 * Measures the width of this border, storing the results into a
579 * pre-existing Insets object.
581 * <p>Although the thickness of the actually painted border
582 * depends on the state of the enclosed component, this
583 * measurement always returns the same amount of pixels. Indeed,
584 * it would be rather confusing if a button was appearing to
585 * change its size depending on whether it is pressed or not.
587 * @param insets an Insets object for holding the result values.
588 * After invoking this method, the <code>left</code>,
589 * <code>right</code>, <code>top</code> and
590 * <code>bottom</code> fields indicate the width of the
591 * border at the respective edge.
593 * @return the same object that was passed for <code>insets</code>.
595 * @see #getBorderInsets()
597 public Insets getBorderInsets(Component c, Insets insets)
599 /* The exact amount has been determined using a test program
600 * that was run on the Sun reference implementation. With
601 * Apple/Sun JDK 1.3.1 on MacOS X 10.1.5, the result is
602 * [3, 3, 3, 3]. With Sun JDK 1.4.1_01 on Linux/x86, the
603 * result is [2, 3, 3, 3]. We use the values from the 1.4.1_01
604 * release.
606 if (insets == null)
607 return new Insets(2, 3, 3, 3);
609 insets.top = 2;
610 insets.bottom = insets.left = insets.right = 3;
611 return insets;
617 * A border that makes its enclosed component appear as lowered
618 * into the surface. Typically used for text fields.
620 * <p><img src="doc-files/BasicBorders.FieldBorder-1.png" width="500"
621 * height="200" alt="[A screen shot of this border]" />
623 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawEtchedRect
625 * @author Sascha Brawer (brawer@dandelis.ch)
627 public static class FieldBorder
628 extends AbstractBorder
629 implements UIResource
632 * Determined using the <code>serialver</code> tool
633 * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
635 static final long serialVersionUID = 949220756998454908L;
639 * The color for drawing the outer half of the top and left
640 * edges.
642 protected Color shadow;
646 * The color for drawing the inner half of the top and left
647 * edges.
649 protected Color darkShadow;
653 * The color for drawing the inner half of the bottom and right
654 * edges.
656 protected Color highlight;
660 * The color for drawing the outer half of the bottom and right
661 * edges.
663 protected Color lightHighlight;
667 * Constructs a new border for drawing a text field in the Basic
668 * look and feel.
670 * @param shadow the color for drawing the outer half
671 * of the top and left edges.
673 * @param darkShadow the color for drawing the inner half
674 * of the top and left edges.
676 * @param highlight the color for drawing the inner half
677 * of the bottom and right edges.
679 * @param lightHighlight the color for drawing the outer half
680 * of the bottom and right edges.
682 public FieldBorder(Color shadow, Color darkShadow,
683 Color highlight, Color lightHighlight)
685 /* These colors usually come from the UIDefaults of the current
686 * look and feel. Use fallback values if the colors are not
687 * supplied. The API specification is silent about what
688 * behavior is expected for null colors, so users should not
689 * rely on this fallback (which is why it is not documented in
690 * the above Javadoc).
692 this.shadow = (shadow != null) ? shadow : Color.gray;
693 this.darkShadow = (darkShadow != null) ? darkShadow : Color.black;
694 this.highlight = (highlight != null) ? highlight : Color.lightGray;
695 this.lightHighlight = (lightHighlight != null)
696 ? lightHighlight : Color.white;
701 * Paints the FieldBorder around a given component.
703 * @param c the component whose border is to be painted.
704 * @param g the graphics for painting.
705 * @param x the horizontal position for painting the border.
706 * @param y the vertical position for painting the border.
707 * @param width the width of the available area for painting the border.
708 * @param height the height of the available area for painting the border.
710 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawEtchedRect
712 public void paintBorder(Component c, Graphics g,
713 int x, int y, int width, int height)
715 BasicGraphicsUtils.drawEtchedRect(g, x, y, width, height,
716 shadow, darkShadow,
717 highlight, lightHighlight);
722 * Measures the width of this border.
724 * @param c the component whose border is to be measured.
725 * If <code>c</code> is an instance of {@link
726 * javax.swing.text.JTextComponent}, its margin is
727 * added to the border size.
729 * @return an Insets object whose <code>left</code>,
730 * <code>right</code>, <code>top</code> and
731 * <code>bottom</code> fields indicate the width of the
732 * border at the respective edge.
734 * @see #getBorderInsets(java.awt.Component, java.awt.Insets)
736 public Insets getBorderInsets(Component c)
738 return getBorderInsets(c, null);
743 * Measures the width of this border, storing the results into a
744 * pre-existing Insets object.
746 * @param c the component whose border is to be measured.
747 * If <code>c</code> is an instance of {@link
748 * javax.swing.text.JTextComponent}, its margin is
749 * added to the border size.
751 * @param insets an Insets object for holding the result values.
752 * After invoking this method, the <code>left</code>,
753 * <code>right</code>, <code>top</code> and
754 * <code>bottom</code> fields indicate the width of the
755 * border at the respective edge.
757 * @return the same object that was passed for <code>insets</code>.
759 * @see #getBorderInsets()
761 public Insets getBorderInsets(Component c, Insets insets)
763 if (insets == null)
764 insets = new Insets(2, 2, 2, 2);
765 else
766 insets.top = insets.left = insets.bottom = insets.right = 2;
768 if (c instanceof JTextComponent)
770 Insets margin = ((JTextComponent) c).getMargin();
771 insets.top += margin.top;
772 insets.left += margin.left;
773 insets.bottom += margin.bottom;
774 insets.right += margin.right;
777 return insets;
783 * An invisible, but spacing border whose margin is determined
784 * by calling the <code>getMargin()</code> method of the enclosed
785 * component. If the enclosed component has no such method,
786 * this border will not occupy any space.
788 * <p><img src="doc-files/BasicBorders.MarginBorder-1.png" width="325"
789 * height="200" alt="[An illustration that shows how MarginBorder
790 * determines its borders]" />
792 * @author Sascha Brawer (brawer@dandelis.ch)
794 public static class MarginBorder
795 extends AbstractBorder
796 implements Serializable, UIResource
799 * Determined using the <code>serialver</code> tool
800 * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
802 static final long serialVersionUID = -3035848353448896090L;
806 * Constructs a new MarginBorder.
808 public MarginBorder()
814 * Measures the width of this border.
816 * @param c the component whose border is to be measured.
818 * @return an Insets object whose <code>left</code>, <code>right</code>,
819 * <code>top</code> and <code>bottom</code> fields indicate the
820 * width of the border at the respective edge.
822 * @see #getBorderInsets(java.awt.Component, java.awt.Insets)
824 public Insets getBorderInsets(Component c)
826 return getBorderInsets(c, new Insets(0, 0, 0, 0));
831 * Determines the insets of this border by calling the
832 * <code>getMargin()</code> method of the enclosed component. The
833 * resulting margin will be stored into the the <code>left</code>,
834 * <code>right</code>, <code>top</code> and <code>bottom</code>
835 * fields of the passed <code>insets</code> parameter.
837 * <p>Unfortunately, <code>getMargin()</code> is not a method of
838 * {@link javax.swing.JComponent} or some other common superclass
839 * of things with margins. While reflection could be used to
840 * determine the existence of this method, this would be slow on
841 * many virtual machines. Therefore, the current implementation
842 * knows about {@link javax.swing.AbstractButton#getMargin()},
843 * {@link javax.swing.JPopupMenu#getMargin()}, {@link
844 * javax.swing.JToolBar#getMargin()}, and {@link
845 * javax.swing.text.JTextComponent}. If <code>c</code> is an
846 * instance of a known class, the respective
847 * <code>getMargin()</code> method is called to determine the
848 * correct margin. Otherwise, a zero-width margin is returned.
850 * @param c the component whose border is to be measured.
852 * @return the same object that was passed for <code>insets</code>,
853 * but with changed fields.
855 public Insets getBorderInsets(Component c, Insets insets)
857 Insets margin = null;
859 /* This is terrible object-oriented design. See the above Javadoc
860 * for an excuse.
862 if (c instanceof AbstractButton)
863 margin = ((AbstractButton) c).getMargin();
864 else if (c instanceof JPopupMenu)
865 margin = ((JPopupMenu) c).getMargin();
866 else if (c instanceof JToolBar)
867 margin = ((JToolBar) c).getMargin();
868 else if (c instanceof JTextComponent)
869 margin = ((JTextComponent) c).getMargin();
871 if (margin == null)
872 insets.top = insets.left = insets.bottom = insets.right = 0;
873 else
875 insets.top = margin.top;
876 insets.left = margin.left;
877 insets.bottom = margin.bottom;
878 insets.right = margin.right;
881 return insets;
887 * A border for drawing a separator line below JMenuBar.
889 * <p><img src="doc-files/BasicBorders.MenuBarBorder-1.png" width="500"
890 * height="140" alt="[A screen shot of a JMenuBar with this border]" />
892 * @author Sascha Brawer (brawer@dandelis.ch)
894 public static class MenuBarBorder
895 extends AbstractBorder
896 implements UIResource
899 * Determined using the <code>serialver</code> tool
900 * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
902 static final long serialVersionUID = -6909056571935227506L;
906 * The shadow color, which is used for the upper line of the
907 * two-pixel thick bottom edge.
909 private Color shadow;
913 * The highlight color, which is used for the lower line of the
914 * two-pixel thick bottom edge.
916 private Color highlight;
920 * Constructs a new MenuBarBorder for drawing a JMenuBar in
921 * the Basic look and feel.
923 * <p><img src="doc-files/BasicBorders.MenuBarBorder-1.png" width="500"
924 * height="140" alt="[A screen shot of a JMenuBar with this
925 * border]" />
927 * @param shadow the shadow color, which is used for the upper
928 * line of the two-pixel thick bottom edge.
930 * @param highlight the shadow color, which is used for the lower
931 * line of the two-pixel thick bottom edge.
933 public MenuBarBorder(Color shadow, Color highlight)
935 /* These colors usually come from the UIDefaults of the current
936 * look and feel. Use fallback values if the colors are not
937 * supplied. The API specification is silent about what
938 * behavior is expected for null colors, so users should not
939 * rely on this fallback (which is why it is not documented in
940 * the above Javadoc).
942 this.shadow = (shadow != null) ? shadow : Color.gray;
943 this.highlight = (highlight != null) ? highlight : Color.white;
948 * Paints the MenuBarBorder around a given component.
950 * @param c the component whose border is to be painted, usually
951 * an instance of {@link javax.swing.JMenuBar}.
953 * @param g the graphics for painting.
954 * @param x the horizontal position for painting the border.
955 * @param y the vertical position for painting the border.
956 * @param width the width of the available area for painting the border.
957 * @param height the height of the available area for painting the border.
959 public void paintBorder(Component c, Graphics g,
960 int x, int y, int width, int height)
962 Color oldColor;
964 /* To understand this code, it might be helpful to look at the
965 * image "BasicBorders.MenuBarBorder-1.png" that is included
966 * with the JavaDoc. It is located in the "doc-files"
967 * subdirectory.
969 oldColor = g.getColor();
970 y = y + height - 2;
973 g.setColor(shadow);
974 g.drawLine(x, y, x + width - 2, y);
975 g.drawLine(x, y + 1, x, y + 1);
976 g.drawLine(x + width - 2, y + 1, x + width - 2, y + 1);
978 g.setColor(highlight);
979 g.drawLine(x + 1, y + 1, x + width - 3, y + 1);
980 g.drawLine(x + width - 1, y, x + width - 1, y + 1);
982 finally
984 g.setColor(oldColor);
990 * Measures the width of this border.
992 * @param c the component whose border is to be measured.
994 * @return an Insets object whose <code>left</code>,
995 * <code>right</code>, <code>top</code> and
996 * <code>bottom</code> fields indicate the width of the
997 * border at the respective edge.
999 * @see #getBorderInsets(java.awt.Component, java.awt.Insets)
1001 public Insets getBorderInsets(Component c)
1003 /* There is no obvious reason for overriding this method, but we
1004 * try to have exactly the same API as the Sun reference
1005 * implementation.
1007 return getBorderInsets(c, null);
1012 * Measures the width of this border, storing the results into a
1013 * pre-existing Insets object.
1015 * @param insets an Insets object for holding the result values.
1016 * After invoking this method, the <code>left</code>,
1017 * <code>right</code>, <code>top</code> and
1018 * <code>bottom</code> fields indicate the width of the
1019 * border at the respective edge.
1021 * @return the same object that was passed for <code>insets</code>.
1023 * @see #getBorderInsets()
1025 public Insets getBorderInsets(Component c, Insets insets)
1027 /* The exact amount has been determined using a test program
1028 * that was run on the Apple/Sun JDK 1.3.1 on MacOS X, and the
1029 * Sun JDK 1.4.1_01 on GNU/Linux for x86. Both gave [0,0,2,0],
1030 * which was expected from looking at the screen shot.
1032 if (insets == null)
1033 return new Insets(0, 0, 2, 0);
1035 insets.left = insets.right = insets.top = 0;
1036 insets.bottom = 2;
1037 return insets;
1043 * A border for drawing radio buttons in the Basic look and feel.
1045 * <p><img src="doc-files/BasicBorders.RadioButtonBorder-1.png" width="300"
1046 * height="135" alt="[A screen shot of this border]" />
1048 * <p>Note about the screen shot: Normally, the
1049 * <code>borderPainted</code> property is <code>false</code> for
1050 * JRadioButtons. For this screen shot, it has been set to
1051 * <code>true</code> so the borders get drawn. Also, a
1052 * concretization of the Basic look and would typically provide
1053 * icons for the various states of radio buttons.
1055 * <p>Note that the focus rectangle is invisible If the radio button
1056 * is currently selected. While it might be debatable whether this
1057 * makes a lot of sense, this behavior can be observed in the Sun
1058 * reference implementation (in JDK 1.3.1 and 1.4.1). The Classpath
1059 * implementation tries to exactly replicate the JDK appearance.
1061 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
1063 * @author Sascha Brawer (brawer@dandelis.ch)
1065 public static class RadioButtonBorder
1066 extends ButtonBorder
1069 * Determined using the <code>serialver</code> tool
1070 * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
1072 static final long serialVersionUID = 1596945751743747369L;
1076 * Constructs a new border for drawing a JRadioButton in
1077 * the Basic look and feel.
1079 * @param shadow the shadow color.
1080 * @param darkShadow a darker variant of the shadow color.
1081 * @param highlight the highlight color.
1082 * @param lightHighlight a brighter variant of the highlight color.
1084 public RadioButtonBorder(Color shadow, Color darkShadow,
1085 Color highlight, Color lightHighlight)
1087 /* The superclass ButtonBorder substitutes null arguments
1088 * with fallback colors.
1090 super(shadow, darkShadow, highlight, lightHighlight);
1095 * Paints the RadioButtonBorder around a given component.
1097 * <p>The Sun implementation always seems to draw exactly
1098 * the same border, irrespective of the state of the button.
1099 * This is rather surprising, but GNU Classpath emulates the
1100 * observable behavior.
1102 * @param c the component whose border is to be painted.
1103 * @param g the graphics for painting.
1104 * @param x the horizontal position for painting the border.
1105 * @param y the vertical position for painting the border.
1106 * @param width the width of the available area for painting the border.
1107 * @param height the height of the available area for painting the border.
1109 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
1111 public void paintBorder(Component c, Graphics g,
1112 int x, int y, int width, int height)
1114 AbstractButton button = null;
1115 ButtonModel bmodel = null;
1116 boolean lowered = false;
1117 boolean focused = false;
1119 if (c instanceof AbstractButton)
1121 button = (AbstractButton) c;
1122 bmodel = button.getModel();
1125 if (bmodel != null)
1127 lowered = button.isSelected()
1128 || (/* mouse inside */ bmodel.isArmed() && bmodel.isPressed());
1129 focused = button.hasFocus() && button.isFocusPainted();
1132 if (lowered)
1133 BasicGraphicsUtils.drawLoweredBezel(g, x, y, width, height,
1134 shadow, darkShadow,
1135 highlight, lightHighlight);
1136 else
1137 BasicGraphicsUtils.drawBezel(g, x, y, width, height,
1138 /* isPressed */ false,
1139 /* isPefault */ focused,
1140 shadow, darkShadow,
1141 highlight, lightHighlight);
1146 * Measures the width of this border.
1148 * @param c the component whose border is to be measured.
1150 * @return an Insets object whose <code>left</code>,
1151 * <code>right</code>, <code>top</code> and
1152 * <code>bottom</code> fields indicate the width of the
1153 * border at the respective edge.
1155 * @see #getBorderInsets(java.awt.Component, java.awt.Insets)
1157 public Insets getBorderInsets(Component c)
1159 /* There is no obvious reason for overriding this method, but we
1160 * try to have exactly the same API as the Sun reference
1161 * implementation.
1163 return getBorderInsets(c, null);
1168 * Measures the width of this border, storing the results into a
1169 * pre-existing Insets object.
1171 * @param insets an Insets object for holding the result values.
1172 * After invoking this method, the <code>left</code>,
1173 * <code>right</code>, <code>top</code> and
1174 * <code>bottom</code> fields indicate the width of the
1175 * border at the respective edge.
1177 * @return the same object that was passed for <code>insets</code>.
1179 * @see #getBorderInsets()
1181 public Insets getBorderInsets(Component c, Insets insets)
1183 /* The exact amount has been determined using a test program
1184 * that was run on the Apple/Sun JDK 1.3.1 on MacOS X, and the
1185 * Sun JDK 1.4.1_01 on GNU/Linux for x86. Both gave [2,2,2,2].
1187 if (insets == null)
1188 return new Insets(2, 2, 2, 2);
1190 insets.left = insets.right = insets.top = insets.bottom = 2;
1191 return insets;
1197 * A one-pixel thick border for rollover buttons, for example in
1198 * tool bars.
1200 * @since 1.4
1201 * @author Sascha Brawer (brawer@dandelis.ch)
1203 public static class RolloverButtonBorder
1204 extends ButtonBorder
1207 * Determined using the <code>serialver</code> tool
1208 * of Sun JDK 1.4.1_01 on GNU/Linux 2.4.20 for x86.
1210 static final long serialVersionUID = 1976364864896996846L;
1214 * Constructs a new border for drawing a roll-over button
1215 * in the Basic look and feel.
1217 * @param shadow the shadow color.
1218 * @param darkShadow a darker variant of the shadow color.
1219 * @param highlight the highlight color.
1220 * @param lightHighlight a brighter variant of the highlight color.
1222 public RolloverButtonBorder(Color shadow, Color darkShadow,
1223 Color highlight, Color lightHighlight)
1225 super(shadow, darkShadow, highlight, lightHighlight);
1230 * Paints the border around a rollover button. If <code>c</code>
1231 * is not an {@link javax.swing.AbstractButton} whose model
1232 * returns <code>true</code> for {@link
1233 * javax.swing.ButtonModel#isRollver}, nothing gets painted at
1234 * all.
1236 * @param c the button whose border is to be painted.
1237 * @param g the graphics for painting.
1238 * @param x the horizontal position for painting the border.
1239 * @param y the vertical position for painting the border.
1240 * @param width the width of the available area for painting the border.
1241 * @param height the height of the available area for painting the border.
1243 public void paintBorder(Component c, Graphics g,
1244 int x, int y, int width, int height)
1246 ButtonModel bmodel = null;
1247 boolean drawPressed;
1248 Color oldColor = g.getColor();
1249 int x2, y2;
1251 if (c instanceof AbstractButton)
1252 bmodel = ((AbstractButton) c).getModel();
1254 /* Draw nothing if c is not a rollover button. */
1255 if ((bmodel == null) || !bmodel.isRollover())
1256 return;
1258 /* Draw nothing if the mouse is pressed, but outside the button. */
1259 if (bmodel.isPressed() && !bmodel.isArmed())
1260 return;
1262 drawPressed = bmodel.isSelected() || bmodel.isPressed();
1263 x2 = x + width - 1;
1264 y2 = y + height - 1;
1268 g.setColor(drawPressed ? shadow : lightHighlight);
1269 g.drawLine(x, y, x2 - 1, y); // top edge
1270 g.drawLine(x, y + 1, x, y2 - 1); // left edge
1272 g.setColor(drawPressed ? lightHighlight : shadow);
1273 g.drawLine(x, y2, x2, y2); // bottom edge
1274 g.drawLine(x2, y, x2, y2 - 1); // right edge
1276 finally
1278 g.setColor(oldColor);
1285 * A border for JSplitPanes in the Basic look and feel. The divider
1286 * in the middle of the JSplitPane has its own border class, of which
1287 * an instance can be obtained with {@link #getSplitPaneDividerBorder()}.
1289 * <p><img src="doc-files/BasicBorders.SplitPaneBorder-1.png" width="520"
1290 * height="200" alt="[A screen shot for JSplitPane.HORIZONTAL_SPLIT]" />
1292 * <p><img src="doc-files/BasicBorders.SplitPaneBorder-2.png" width="520"
1293 * height="200" alt="[A screen shot for JSplitPane.VERTICAL_SPLIT]" />
1295 * <p>In contrast to the other borders of the Basic look and feel,
1296 * this class is not serializable. While this might be unintended,
1297 * GNU Classpath follows the specification in order to be fully
1298 * compatible with the Sun reference implementation.
1300 * <p>In the Sun JDK, the bottom edge of the divider also gets
1301 * painted if the orientation of the enclosed JSplitPane is
1302 * <code>JSplitPane.VERTICAL_SPLIT</code> (at least in versions
1303 * 1.3.1 and 1.4.1). GNU Classpath does not replicate this bug. A
1304 * report has been filed with Sun (bug ID 4885629).
1306 * <p>Note that the bottom left pixel of the border has a different
1307 * color depending on the orientation of the enclosed JSplitPane.
1308 * Although this is visually inconsistent, Classpath replicates the
1309 * appearance of the Sun reference implementation. A bug report has
1310 * been filed with Sun (review ID 188774).
1312 * @see {@link #getSplitPaneBorder()}
1313 * @see {@link #getSplitPaneDividerBorder()}
1315 * @author Sascha Brawer (brawer@dandelis.ch)
1317 public static class SplitPaneBorder
1318 implements Border, UIResource
1321 * Indicates that the top edge shall be not be painted
1322 * by {@link #paintRect(java.awt.Graphics, int, int, int, int, int)}.
1324 private static final int SUPPRESS_TOP = 1;
1328 * Indicates that the left edge shall be not be painted
1329 * by {@link #paintRect(java.awt.Graphics, int, int, int, int, int)}.
1331 private static final int SUPPRESS_LEFT = 2;
1335 * Indicates that the bottom edge shall be not be painted
1336 * by {@link #paintRect(java.awt.Graphics, int, int, int, int, int)}.
1338 private static final int SUPPRESS_BOTTOM = 4;
1342 * Indicates that the right edge shall be not be painted
1343 * by {@link #paintRect(java.awt.Graphics, int, int, int, int, int)}.
1345 private static final int SUPPRESS_RIGHT = 8;
1349 * The color for drawing the bottom and right edges of the border.
1351 protected Color highlight;
1355 * The color for drawing the top and left edges of the border.
1357 protected Color shadow;
1361 * Constructs a new border for drawing a JSplitPane in the Basic
1362 * look and feel. The divider in the middle of the JSplitPane has
1363 * its own border class, <code>SplitPaneDividerBorder</code>.
1365 * @param shadow the shadow color.
1366 * @param highlight the highlight color.
1368 public SplitPaneBorder(Color highlight, Color shadow)
1370 /* These colors usually come from the UIDefaults of the current
1371 * look and feel. Use fallback values if the colors are not
1372 * supplied. The API specification is silent about what
1373 * behavior is expected for null colors, so users should not
1374 * rely on this fallback (which is why it is not documented in
1375 * the above Javadoc).
1377 this.shadow = (shadow != null) ? shadow : Color.black;
1378 this.highlight = (highlight != null) ? highlight : Color.white;
1383 * Paints the border around a <code>JSplitPane</code>.
1385 * <p><img src="doc-files/BasicBorders.SplitPaneBorder-1.png" width="520"
1386 * height="200" alt="[A screen shot for JSplitPane.HORIZONTAL_SPLIT]" />
1388 * <p><img src="doc-files/BasicBorders.SplitPaneBorder-2.png" width="520"
1389 * height="200" alt="[A screen shot for JSplitPane.VERTICAL_SPLIT]" />
1391 * @param c the <code>JSplitPane</code> whose border is to be painted.
1392 * @param g the graphics for painting.
1393 * @param x the horizontal position for painting the border.
1394 * @param y the vertical position for painting the border.
1395 * @param width the width of the available area for painting the border.
1396 * @param height the height of the available area for painting the border.
1398 public void paintBorder(Component c, Graphics g,
1399 int x, int y, int width, int height)
1401 JSplitPane splitPane;
1402 Component content;
1404 if (!(c instanceof JSplitPane))
1405 return;
1407 splitPane = (JSplitPane) c;
1408 switch (splitPane.getOrientation())
1410 case JSplitPane.HORIZONTAL_SPLIT:
1411 if ((content = splitPane.getLeftComponent()) != null)
1412 paintRect(g, SUPPRESS_RIGHT, true, x, y, content.getBounds());
1413 if ((content = splitPane.getRightComponent()) != null)
1414 paintRect(g, SUPPRESS_LEFT, true, x, y, content.getBounds());
1415 break;
1417 case JSplitPane.VERTICAL_SPLIT:
1418 if ((content = splitPane.getTopComponent()) != null)
1419 paintRect(g, SUPPRESS_BOTTOM, false, x, y, content.getBounds());
1420 if ((content = splitPane.getBottomComponent()) != null)
1421 paintRect(g, SUPPRESS_TOP, false, x, y, content.getBounds());
1422 break;
1428 * Paints a border around a child of a <code>JSplitPane</code>,
1429 * omitting some of the edges.
1431 * @param g the graphics for painting.
1433 * @param suppress a bit mask indicating the set of suppressed
1434 * edges, for example <code>SUPPRESS_TOP | SUPPRESS_RIGHT</code>.
1436 * @param x the x coordinate of the SplitPaneBorder.
1438 * @param y the y coordinate of the SplitPaneBorder.
1440 * @param shadeBottomLeftPixel <code>true</code> to paint the
1441 * bottom left pixel in the shadow color,
1442 * <code>false</code> for the highlight color. The Basic
1443 * look and feel uses the highlight color for the bottom
1444 * left pixel of the border of a JSplitPane whose
1445 * orientation is VERTICAL_SPLIT, and the shadow color
1446 * otherwise. While this might be a strange distinction,
1447 * Classpath tries to look identical to the reference
1448 * implementation. A bug report has been filed with Sun;
1449 * its review ID is 188774. We currently replicate the
1450 * Sun behavior.
1452 * @param rect the bounds of the child of JSplitPane whose
1453 * border is to be painted.
1455 private void paintRect(Graphics g, int suppress,
1456 boolean shadeBottomLeftPixel,
1457 int x, int y,
1458 Rectangle rect)
1460 if (rect == null)
1461 return;
1463 /* On each edge, the border exceeds the enclosed child by one
1464 * pixel. See the image "BasicBorders.SplitPaneBorder-1.png" in
1465 * the directory "doc-files".
1467 x += rect.x - 1;
1468 y += rect.y - 1;
1469 int right = x + rect.width + 1;
1470 int bottom = y + rect.height + 1;
1472 Color oldColor = g.getColor();
1475 g.setColor(shadow);
1476 if ((suppress & SUPPRESS_TOP) == 0)
1477 g.drawLine(x, y, right, y);
1478 if ((suppress & SUPPRESS_LEFT) == 0)
1479 g.drawLine(x, y, x, bottom);
1480 else
1481 g.drawLine(x, bottom, x, bottom); // one pixel
1483 g.setColor(highlight);
1484 if ((suppress & SUPPRESS_BOTTOM) == 0)
1485 g.drawLine(x + (shadeBottomLeftPixel ? 1 : 0), bottom, right, bottom);
1486 else if (!shadeBottomLeftPixel)
1487 g.drawLine(x, bottom, x, bottom); // one pixel
1489 if ((suppress & SUPPRESS_RIGHT) == 0)
1490 g.drawLine(right, y, right, bottom);
1492 finally
1494 g.setColor(oldColor);
1500 * Measures the width of this border.
1502 * @param c the component whose border is to be measured, usually
1503 * an instance of {@link javax.swing.JSplitPane}.
1505 * @return an Insets object whose <code>left</code>,
1506 * <code>right</code>, <code>top</code> and
1507 * <code>bottom</code> fields indicate the width of the
1508 * border at the respective edge.
1510 public Insets getBorderInsets(Component c)
1512 return new Insets(1, 1, 1, 1);
1517 * Determines whether this border fills every pixel in its area
1518 * when painting.
1520 * @return <code>false</code> because this border does not
1521 * paint over the pixels where the divider joins
1522 * the border.
1524 public boolean isBorderOpaque()
1526 /* Strangely, the Sun implementation (tested with JDK 1.3.1 and
1527 * 1.4.1_01) seems to always return true. It could be a bug,
1528 * but without knowing the details of their implementation, it is
1529 * hard to decide.
1531 return false;
1537 * A border for the divider inside a JSplitPane.
1539 * <p><img src="doc-files/BasicBorders.SplitPaneDividerBorder-1.png"
1540 * width="520" height="200" alt="[A screen shot of this border]" />
1542 * @author Sascha Brawer (brawer@dandelis.ch)
1544 private static class SplitPaneDividerBorder
1545 implements Border, UIResource, Serializable
1548 * The highlight color, which is drawn on the left or top edge
1549 * depending on the orientation of the JSplitPanel.
1551 protected Color highlight;
1555 * The highlight color, which is drawn on the right or bottom edge
1556 * depending on the orientation of the JSplitPanel.
1558 protected Color shadow;
1562 * Constructs a new border for drawing the divider of a JSplitPane
1563 * in the Basic look and feel. The outer parts of the JSplitPane have
1564 * their own border class, <code>SplitPaneBorder</code>.
1566 * @param shadow the shadow color.
1567 * @param highlight the highlight color.
1569 public SplitPaneDividerBorder(Color highlight, Color shadow)
1571 this.highlight = (highlight != null) ? highlight : Color.white;
1572 this.shadow = (shadow != null) ? shadow : Color.black;
1577 * Paints the border around the divider of a <code>JSplitPane</code>.
1579 * <p><img src="doc-files/BasicBorders.SplitPaneDividerBorder-1.png"
1580 * width="520" height="200" alt="[A picture that shows which pixels
1581 * get painted in what color]" />
1583 * @param c the <code>JSplitPane</code> whose divider&#x2019;s border
1584 * is to be painted.
1585 * @param g the graphics for painting.
1586 * @param x the horizontal position for painting the border.
1587 * @param y the vertical position for painting the border.
1588 * @param width the width of the available area for painting the border.
1589 * @param height the height of the available area for painting the border.
1591 public void paintBorder(Component c, Graphics g,
1592 int x, int y, int width, int height)
1594 Color oldColor, dcol;
1595 int x2, y2;
1596 JSplitPane sp;
1598 sp = getSplitPane(c);
1599 if (sp == null)
1600 return;
1602 x2 = x + width - 1;
1603 y2 = y + height - 1;
1604 oldColor = g.getColor();
1605 dcol = c.getBackground();
1608 switch (sp.getOrientation())
1610 case JSplitPane.HORIZONTAL_SPLIT:
1611 g.setColor(dcol);
1612 g.drawLine(x + 1, y, x2 - 1, y);
1613 g.drawLine(x + 1, y2, x2 - 1, y2);
1614 g.setColor(sp.getLeftComponent() != null ? highlight : dcol);
1615 g.drawLine(x, y, x, y2);
1616 g.setColor(sp.getRightComponent() != null ? shadow : dcol);
1617 g.drawLine(x2, y, x2, y2);
1618 break;
1620 case JSplitPane.VERTICAL_SPLIT:
1621 g.setColor(dcol);
1622 g.drawLine(x, y + 1, x, y2 - 1);
1623 g.drawLine(x2, y + 1, x2, y2 - 1);
1624 g.setColor(sp.getTopComponent() != null ? highlight : dcol);
1625 g.drawLine(x, y, x2, y);
1626 g.setColor(sp.getBottomComponent() != null ? shadow : dcol);
1627 g.drawLine(x, y2, x2, y2);
1628 break;
1631 finally
1633 g.setColor(oldColor);
1639 * Measures the width of this border.
1641 * @param c the component whose border is to be measured, usually
1642 * an instance of {@link javax.swing.JSplitPane}.
1644 * @return an Insets object whose <code>left</code>,
1645 * <code>right</code>, <code>top</code> and
1646 * <code>bottom</code> fields indicate the width of the
1647 * border at the respective edge.
1649 public Insets getBorderInsets(Component c)
1651 return new Insets(1, 1, 1, 1);
1656 * Determines whether this border fills every pixel in its area
1657 * when painting.
1659 * @return <code>true</code> if both highlight and shadow
1660 * color are fully opaque.
1662 public boolean isBorderOpaque()
1664 return (highlight.getAlpha() == 255) && (shadow.getAlpha() == 255);
1669 * Determines the JSplitPane whose divider is being painted.
1671 * @param c an instance of BasicSplitPaneDivider.
1673 * @return a <code>JSplitPane</code>, or <code>null</code> if
1674 * <code>c</code> is not an instance of {@link
1675 * javax.swing.plaf.basic.BasicSplitPaneDivider}.
1677 private JSplitPane getSplitPane(Component c)
1679 if (c instanceof BasicSplitPaneDivider)
1680 return (((BasicSplitPaneDivider) c).getBasicSplitPaneUI())
1681 .getSplitPane();
1682 else
1683 return null;
1689 * A border for toggle buttons in the Basic look and feel.
1691 * <p><img src="doc-files/BasicBorders.ToggleButtonBorder-1.png"
1692 * width="270" height="135" alt="[A screen shot of this border]" />
1694 * <p>The Sun implementation always seems to draw exactly
1695 * the same border, irrespective of the state of the button.
1696 * This is rather surprising, but GNU Classpath emulates the
1697 * observable behavior.
1699 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
1701 * @author Sascha Brawer (brawer@dandelis.ch)
1703 public static class ToggleButtonBorder
1704 extends ButtonBorder
1707 * Determined using the <code>serialver</code> tool
1708 * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
1710 static final long serialVersionUID = -3528666548001058394L;
1714 * Constructs a new border for drawing a JToggleButton in
1715 * the Basic look and feel.
1717 * @param shadow the shadow color.
1718 * @param darkShadow a darker variant of the shadow color.
1719 * @param highlight the highlight color.
1720 * @param lightHighlight a brighter variant of the highlight color.
1722 public ToggleButtonBorder(Color shadow, Color darkShadow,
1723 Color highlight, Color lightHighlight)
1725 /* The superclass ButtonBorder substitutes null arguments
1726 * with fallback colors.
1728 super(shadow, darkShadow, highlight, lightHighlight);
1733 * Paints the ToggleButtonBorder around a given component.
1735 * <p>The Sun implementation always seems to draw exactly
1736 * the same border, irrespective of the state of the button.
1737 * This is rather surprising, but GNU Classpath emulates the
1738 * observable behavior.
1740 * @param c the component whose border is to be painted.
1741 * @param g the graphics for painting.
1742 * @param x the horizontal position for painting the border.
1743 * @param y the vertical position for painting the border.
1744 * @param width the width of the available area for painting the border.
1745 * @param height the height of the available area for painting the border.
1747 * @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
1749 public void paintBorder(Component c, Graphics g,
1750 int x, int y, int width, int height)
1752 /* The author of this code tried various variants for setting
1753 * the state of the enclosed JToggleButton, but it seems that
1754 * the drawn border is always identical. Weird, because this
1755 * means that the user does not see whether the JToggleButton
1756 * is selected or not.
1758 BasicGraphicsUtils.drawBezel(g, x, y, width, height,
1759 /* pressed */ false,
1760 /* default */ false,
1761 shadow, darkShadow,
1762 highlight, lightHighlight);
1767 * Measures the width of this border.
1769 * @param c the component whose border is to be measured.
1771 * @return an Insets object whose <code>left</code>,
1772 * <code>right</code>, <code>top</code> and
1773 * <code>bottom</code> fields indicate the width of the
1774 * border at the respective edge.
1776 * @see #getBorderInsets(java.awt.Component, java.awt.Insets)
1778 public Insets getBorderInsets(Component c)
1780 /* There is no obvious reason for overriding this method, but we
1781 * try to have exactly the same API as the Sun reference
1782 * implementation.
1784 return getBorderInsets(c, null);
1789 * Measures the width of this border, storing the results into a
1790 * pre-existing Insets object.
1792 * @param insets an Insets object for holding the result values.
1793 * After invoking this method, the <code>left</code>,
1794 * <code>right</code>, <code>top</code> and
1795 * <code>bottom</code> fields indicate the width of the
1796 * border at the respective edge.
1798 * @return the same object that was passed for <code>insets</code>.
1800 * @see #getBorderInsets()
1802 public Insets getBorderInsets(Component c, Insets insets)
1804 /* The exact amount has been determined using a test program
1805 * that was run on the Apple/Sun JDK 1.3.1 on MacOS X, and the
1806 * Sun JDK 1.4.1_01 on GNU/Linux for x86. Both gave [2,2,2,2].
1808 if (insets == null)
1809 return new Insets(2, 2, 2, 2);
1811 insets.left = insets.right = insets.top = insets.bottom = 2;
1812 return insets;