From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- .../javax/swing/border/AbstractBorder.java | 199 ++++ .../classpath/javax/swing/border/BevelBorder.java | 584 +++++++++++ libjava/classpath/javax/swing/border/Border.java | 103 ++ .../javax/swing/border/CompoundBorder.java | 255 +++++ .../classpath/javax/swing/border/EmptyBorder.java | 223 ++++ .../classpath/javax/swing/border/EtchedBorder.java | 414 ++++++++ .../classpath/javax/swing/border/LineBorder.java | 347 +++++++ .../classpath/javax/swing/border/MatteBorder.java | 407 ++++++++ .../javax/swing/border/SoftBevelBorder.java | 327 ++++++ .../classpath/javax/swing/border/TitledBorder.java | 1078 ++++++++++++++++++++ .../javax/swing/border/doc-files/BevelBorder-1.png | Bin 0 -> 4440 bytes .../javax/swing/border/doc-files/BevelBorder-2.png | Bin 0 -> 3667 bytes .../javax/swing/border/doc-files/BevelBorder-3.png | Bin 0 -> 4981 bytes .../javax/swing/border/doc-files/EmptyBorder-1.png | Bin 0 -> 11522 bytes .../swing/border/doc-files/EtchedBorder-1.png | Bin 0 -> 4820 bytes .../swing/border/doc-files/EtchedBorder-2.png | Bin 0 -> 3850 bytes .../javax/swing/border/doc-files/LineBorder-1.png | Bin 0 -> 6133 bytes .../javax/swing/border/doc-files/MatteBorder-1.png | Bin 0 -> 5447 bytes .../javax/swing/border/doc-files/MatteBorder-2.png | Bin 0 -> 5099 bytes .../javax/swing/border/doc-files/MatteBorder-3.png | Bin 0 -> 5726 bytes .../javax/swing/border/doc-files/MatteBorder-4.png | Bin 0 -> 7220 bytes .../javax/swing/border/doc-files/MatteBorder-5.png | Bin 0 -> 7971 bytes .../javax/swing/border/doc-files/MatteBorder-6.png | Bin 0 -> 5511 bytes .../swing/border/doc-files/SoftBevelBorder-1.png | Bin 0 -> 4877 bytes .../swing/border/doc-files/SoftBevelBorder-2.png | Bin 0 -> 3860 bytes .../swing/border/doc-files/SoftBevelBorder-3.png | Bin 0 -> 5155 bytes libjava/classpath/javax/swing/border/package.html | 47 + 27 files changed, 3984 insertions(+) create mode 100644 libjava/classpath/javax/swing/border/AbstractBorder.java create mode 100644 libjava/classpath/javax/swing/border/BevelBorder.java create mode 100644 libjava/classpath/javax/swing/border/Border.java create mode 100644 libjava/classpath/javax/swing/border/CompoundBorder.java create mode 100644 libjava/classpath/javax/swing/border/EmptyBorder.java create mode 100644 libjava/classpath/javax/swing/border/EtchedBorder.java create mode 100644 libjava/classpath/javax/swing/border/LineBorder.java create mode 100644 libjava/classpath/javax/swing/border/MatteBorder.java create mode 100644 libjava/classpath/javax/swing/border/SoftBevelBorder.java create mode 100644 libjava/classpath/javax/swing/border/TitledBorder.java create mode 100644 libjava/classpath/javax/swing/border/doc-files/BevelBorder-1.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/BevelBorder-2.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/BevelBorder-3.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/EmptyBorder-1.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/EtchedBorder-1.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/EtchedBorder-2.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/LineBorder-1.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/MatteBorder-1.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/MatteBorder-2.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/MatteBorder-3.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/MatteBorder-4.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/MatteBorder-5.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/MatteBorder-6.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-1.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-2.png create mode 100644 libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-3.png create mode 100644 libjava/classpath/javax/swing/border/package.html (limited to 'libjava/classpath/javax/swing/border') diff --git a/libjava/classpath/javax/swing/border/AbstractBorder.java b/libjava/classpath/javax/swing/border/AbstractBorder.java new file mode 100644 index 000000000..f75bcbbc2 --- /dev/null +++ b/libjava/classpath/javax/swing/border/AbstractBorder.java @@ -0,0 +1,199 @@ +/* AbstractBorder.java -- + Copyright (C) 2003, 2006, Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.border; + +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Rectangle; +import java.io.Serializable; + + +/** + * An invisible zero-width border, serving as a base class for + * implementing more interesting borders. + * + * @author Sascha Brawer (brawer@dandelis.ch) + * @author Ronald Veldema (rveldema@cs.vu.nl) + */ +public abstract class AbstractBorder implements Border, Serializable +{ + static final long serialVersionUID = -545885975315191844L; + + /** + * Constructs a new AbstractBorder. + */ + public AbstractBorder() + { + // Nothing to do here. + } + + /** + * Performs nothing, because the default implementation provided by + * this class is an invisible, zero-width border. Subclasses will + * likely want to override this method, but they are not required + * to do so. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + public void paintBorder(Component c, Graphics g, int x, int y, int width, + int height) + { + // A previous version of Classpath had emitted a warning when + // this method was called. The warning was removed because it is + // perfectly legal for a subclass to not override the paintBorder + // method. An example would be EmptyBorder. + } + + /** + * Returns the insets required for drawing this border around the specified + * component. + * + * @param c the component that the border applies to (ignored here, + * subclasses may use it). + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge, which is zero + * for the default implementation provided by AbstractButton. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets(Component c) + { + return new Insets(0, 0, 0, 0); + } + + /** + * Returns the insets required for drawing this border around the specified + * component. The default implementation provided here sets the + * left, right, top and + * bottom fields of the passed insets parameter to + * zero. + * + * @param c the component that the border applies to (ignored here, + * subclasses may use it). + * @param insets an instance that will be overwritten and returned as the + * result (null not permitted). + * + * @return The border insets (the same object that was passed as the + * insets argument). + * + * @see #getBorderInsets(Component) + * + * @throws NullPointerException if insets is null. + */ + public Insets getBorderInsets(Component c, Insets insets) + { + insets.left = insets.right = insets.top = insets.bottom = 0; + return insets; + } + + /** + * Determines whether or not this border is opaque. An opaque border + * fills every pixel in its area when painting. Partially + * translucent borders must return false, or ugly + * artifacts can appear on screen. The default implementation + * provided here always returns false. + * + * @return false. + */ + public boolean isBorderOpaque() + { + return false; + } + + /** + * Returns a rectangle that covers the specified area minus the insets + * required to draw this border. Components that wish to determine an area + * into which they can safely draw without intersecting with a border might + * want to use this helper method. + * + * @param c the component in the center of this border. + * @param x the horizontal position of the border. + * @param y the vertical position of the border. + * @param width the width of the available area for the border. + * @param height the height of the available area for the border. + * + * @return The interior rectangle. + */ + public Rectangle getInteriorRectangle(Component c, int x, int y, int width, + int height) + { + return getInteriorRectangle(c, this, x, y, width, height); + } + + /** + * Returns a rectangle that covers the specified area minus the insets + * required to draw the specified border (if the border is null, + * zero insets are assumed). Components that wish to determine an area into + * which they can safely draw without intersecting with a border might want + * to use this helper method. + * + * @param c the component in the center of this border. + * @param b the border (null permitted). + * @param x the horizontal position of the border. + * @param y the vertical position of the border. + * @param width the width of the available area for the border. + * @param height the height of the available area for the border. + * + * @return The interior rectangle. + */ + public static Rectangle getInteriorRectangle(Component c, Border b, int x, + int y, int width, int height) + { + Insets borderInsets; + + if (b != null) + { + borderInsets = b.getBorderInsets(c); + x += borderInsets.left; + y += borderInsets.top; + width -= borderInsets.left + borderInsets.right; + height -= borderInsets.top + borderInsets.bottom; + } + + return new Rectangle(x, y, width, height); + } +} diff --git a/libjava/classpath/javax/swing/border/BevelBorder.java b/libjava/classpath/javax/swing/border/BevelBorder.java new file mode 100644 index 000000000..b91961d66 --- /dev/null +++ b/libjava/classpath/javax/swing/border/BevelBorder.java @@ -0,0 +1,584 @@ +/* BevelBorder.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.swing.border; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; + + +/** + * A rectangular, two pixel thick border that causes the enclosed area + * to appear as if it was raising out of or lowered into the screen. Some + * LookAndFeels use this kind of border for rectangular buttons. + * + *

A BevelBorder has a highlight and a shadow color. In the raised + * variant, the highlight color is used for the top and left edges, + * and the shadow color is used for the bottom and right edge. For an + * image, see the documentation of the individual constructors. + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class BevelBorder extends AbstractBorder +{ + /** + * Determined using the serialver tool + * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. + */ + static final long serialVersionUID = -1034942243356299676L; + + + /** + * Indicates that the BevelBorder looks like if the enclosed area was + * raising out of the screen. + */ + public static final int RAISED = 0; + + + /** + * Indicates that the BevelBorder looks like if the enclosed area was + * pressed into the screen. + */ + public static final int LOWERED = 1; + + + /** + * The type of this BevelBorder, which is either {@link #RAISED} + * or {@link #LOWERED}. + */ + protected int bevelType; + + + /** + * The outer highlight color, or null to indicate that + * the color shall be derived from the background of the component + * whose border is being painted. + */ + protected Color highlightOuter; + + + /** + * The inner highlight color, or null to indicate that + * the color shall be derived from the background of the component + * whose border is being painted. + */ + protected Color highlightInner; + + + /** + * The outer shadow color, or null to indicate that the + * color shall be derived from the background of the component whose + * border is being painted. + */ + protected Color shadowOuter; + + + /** + * The inner shadow color, or null to indicate that the + * color shall be derived from the background of the component whose + * border is being painted. + */ + protected Color shadowInner; + + + /** + * Constructs a BevelBorder whose colors will be derived from the + * background of the enclosed component. The background color is + * retrieved each time the border is painted, so a BevelBorder + * constructed by this method will automatically reflect a change + * to the component’s background color. + * + *

[An illustration showing raised and lowered BevelBorders] + * + * @param bevelType the desired appearance of the border. The value + * must be either {@link #RAISED} or {@link #LOWERED}. + * + * @throws IllegalArgumentException if bevelType has + * an unsupported value. + */ + public BevelBorder(int bevelType) + { + if ((bevelType != RAISED) && (bevelType != LOWERED)) + throw new IllegalArgumentException(); + + this.bevelType = bevelType; + } + + + /** + * Constructs a BevelBorder given its appearance type and two colors + * for its highlight and shadow. + * + *

[An illustration showing BevelBorders that were constructed
+   * with this method] + * + * @param bevelType the desired appearance of the border. The value + * must be either {@link #RAISED} or {@link #LOWERED}. + * + * @param highlight the color that will be used for the inner + * side of the highlighted edges (top and left if + * if bevelType is {@link #RAISED}; bottom + * and right otherwise). The color for the outer side + * is a brightened version of this color. + * + * @param shadow the color that will be used for the outer + * side of the shadowed edges (bottom and right + * if bevelType is {@link #RAISED}; top + * and left otherwise). The color for the inner side + * is a brightened version of this color. + * + * @throws IllegalArgumentException if bevelType has + * an unsupported value. + * + * @throws NullPointerException if highlight or + * shadow is null. + * + * @see java.awt.Color#brighter() + */ + public BevelBorder(int bevelType, Color highlight, Color shadow) + { + this(bevelType, + /* highlightOuter */ highlight.brighter(), + /* highlightInner */ highlight, + /* shadowOuter */ shadow, + /* shadowInner */ shadow.brighter()); + } + + + /** + * Constructs a BevelBorder given its appearance type and all + * colors. + * + *

[An illustration showing BevelBorders that were constructed
+   * with this method] + * + * @param bevelType the desired appearance of the border. The value + * must be either {@link #RAISED} or {@link #LOWERED}. + * + * @param highlightOuter the color that will be used for the outer + * side of the highlighted edges (top and left if + * bevelType is {@link #RAISED}; bottom and + * right otherwise). + * + * @param highlightInner the color that will be used for the inner + * side of the highlighted edges. + * + * @param shadowOuter the color that will be used for the outer + * side of the shadowed edges (bottom and right + * if bevelType is {@link #RAISED}; top + * and left otherwise). + * + * @param shadowInner the color that will be used for the inner + * side of the shadowed edges. + * + * @throws IllegalArgumentException if bevelType has + * an unsupported value. + * + * @throws NullPointerException if one of the passed colors + * is null. + */ + public BevelBorder(int bevelType, + Color highlightOuter, Color highlightInner, + Color shadowOuter, Color shadowInner) + { + this(bevelType); // checks the validity of bevelType + + if ((highlightOuter == null) || (highlightInner == null) + || (shadowOuter == null) || (shadowInner == null)) + throw new NullPointerException(); + + this.highlightOuter = highlightOuter; + this.highlightInner = highlightInner; + this.shadowOuter = shadowOuter; + this.shadowInner = shadowInner; + } + + + /** + * Paints the border for a given component. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + public void paintBorder(Component c, Graphics g, + int x, int y, int width, int height) + { + switch (bevelType) + { + case RAISED: + paintRaisedBevel(c, g, x, y, width, height); + break; + + case LOWERED: + paintLoweredBevel(c, g, x, y, width, height); + break; + } + } + + + /** + * Measures the width of this border. + * + * @param c the component whose border is to be measured. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets(Component c) + { + return new Insets(2, 2, 2, 2); + } + + + /** + * Measures the width of this border, storing the results into a + * pre-existing Insets object. + * + * @param insets an Insets object for holding the result values. + * After invoking this method, the left, + * right, top and + * bottom fields indicate the width of the + * border at the respective edge. + * + * @return the same object that was passed for insets. + * + * @see #getBorderInsets(Component) + */ + public Insets getBorderInsets(Component c, Insets insets) + { + insets.left = insets.right = insets.top = insets.bottom = 2; + return insets; + } + + + /** + * Determines the color that will be used for the outer side of + * highlighted edges when painting the border. If a highlight color + * has been specified upon constructing the border, that color is + * returned. Otherwise, the inner highlight color is brightened. + * + * @param c the component enclosed by this border. + * + * @return The color. + * + * @see #getHighlightInnerColor(java.awt.Component) + * @see java.awt.Color#brighter() + */ + public Color getHighlightOuterColor(Component c) + { + if (highlightOuter != null) + return highlightOuter; + else + return getHighlightInnerColor(c).brighter(); + } + + + /** + * Determines the color that will be used for the inner side of + * highlighted edges when painting the border. If a highlight color + * has been specified upon constructing the border, that color is + * returned. Otherwise, the background color of the enclosed + * component is brightened. + * + * @param c the component enclosed by this border. + * + * @return The color. + * + * @see java.awt.Component#getBackground() + * @see java.awt.Color#brighter() + */ + public Color getHighlightInnerColor(Component c) + { + if (highlightInner != null) + return highlightInner; + else + return c.getBackground().brighter(); + } + + + /** + * Determines the color that will be used for the inner side of + * shadowed edges when painting the border. If a shadow color has + * been specified upon constructing the border, that color is + * returned. Otherwise, the background color of the enclosed + * component is darkened. + * + * @param c the component enclosed by this border. + * + * @return The color. + * + * @see java.awt.Component#getBackground() + * @see java.awt.Color#darker() + */ + public Color getShadowInnerColor(Component c) + { + if (shadowInner != null) + return shadowInner; + else + return c.getBackground().darker(); + } + + + /** + * Determines the color that will be used for the outer side of + * shadowed edges when painting the border. If a shadow color + * has been specified upon constructing the border, that color is + * returned. Otherwise, the inner shadow color is darkened. + * + * @param c the component enclosed by this border. + * + * @return The color. + * + * @see #getShadowInnerColor(java.awt.Component) + * @see java.awt.Color#darker() + */ + public Color getShadowOuterColor(Component c) + { + if (shadowOuter != null) + return shadowOuter; + else + return getShadowInnerColor(c).darker(); + } + + + /** + * Returns the color that will be used for the outer side of + * highlighted edges when painting the border, or null + * if that color will be derived from the background of the enclosed + * Component. + * + * @return The color (possibly null). + */ + public Color getHighlightOuterColor() + { + return highlightOuter; + } + + + /** + * Returns the color that will be used for the inner side of + * highlighted edges when painting the border, or null + * if that color will be derived from the background of the enclosed + * Component. + * + * @return The color (possibly null). + */ + public Color getHighlightInnerColor() + { + return highlightInner; + } + + + /** + * Returns the color that will be used for the inner side of + * shadowed edges when painting the border, or null if + * that color will be derived from the background of the enclosed + * Component. + * + * @return The color (possibly null). + */ + public Color getShadowInnerColor() + { + return shadowInner; + } + + + /** + * Returns the color that will be used for the outer side of + * shadowed edges when painting the border, or null if + * that color will be derived from the background of the enclosed + * Component. + * + * @return The color (possibly null). + */ + public Color getShadowOuterColor() + { + return shadowOuter; + } + + + /** + * Returns the appearance of this border, which is either {@link + * #RAISED} or {@link #LOWERED}. + * + * @return The bevel type ({@link #RAISED} or {@link #LOWERED}). + */ + public int getBevelType() + { + return bevelType; + } + + + /** + * Determines whether this border fills every pixel in its area + * when painting. + * + *

If the border colors are derived from the background color of + * the enclosed component, the result is true because + * the derivation method always returns opaque colors. Otherwise, + * the result depends on the opacity of the individual colors. + * + * @return true if the border is fully opaque, or + * false if some pixels of the background + * can shine through the border. + */ + public boolean isBorderOpaque() + { + /* If the colors are to be drived from the enclosed Component's + * background color, the border is guaranteed to be fully opaque + * because Color.brighten() and Color.darken() always return an + * opaque color. + */ + return + ((highlightOuter == null) || (highlightOuter.getAlpha() == 255)) + && ((highlightInner == null) || (highlightInner.getAlpha() == 255)) + && ((shadowInner == null) || (shadowInner.getAlpha() == 255)) + && ((shadowOuter == null) || (shadowOuter.getAlpha() == 255)); + } + + + /** + * Paints a raised bevel border around a component. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + protected void paintRaisedBevel(Component c, Graphics g, + int x, int y, int width, int height) + { + paintBevel(g, x, y, width, height, + getHighlightOuterColor(c), getHighlightInnerColor(c), + getShadowInnerColor(c), getShadowOuterColor(c)); + } + + + /** + * Paints a lowered bevel border around a component. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + protected void paintLoweredBevel(Component c, Graphics g, + int x, int y, int width, int height) + { + paintBevel(g, x, y, width, height, + getShadowInnerColor(c), getShadowOuterColor(c), + getHighlightInnerColor(c), getHighlightOuterColor(c)); + } + + + /** + * Paints a two-pixel bevel in four colors. + * + *

+   * ++++++++++++
+   * +..........#    + = color a
+   * +.        X#    . = color b
+   * +.        X#    X = color c
+   * +.XXXXXXXXX#    # = color d
+   * ############
+ * + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + * @param a the color for the outer side of the top and left edges. + * @param b the color for the inner side of the top and left edges. + * @param c the color for the inner side of the bottom and right edges. + * @param d the color for the outer side of the bottom and right edges. + */ + private static void paintBevel(Graphics g, + int x, int y, int width, int height, + Color a, Color b, Color c, Color d) + { + Color oldColor; + + oldColor = g.getColor(); + g.translate(x, y); + width = width - 1; + height = height - 1; + + try + { + /* To understand this code, it might be helpful to look at the + * images that are included with the JavaDoc. They are located + * in the "doc-files" subdirectory. + */ + g.setColor(a); + g.drawLine(0, 0, width, 0); // a, horizontal + g.drawLine(0, 1, 0, height); // a, vertical + + g.setColor(b); + g.drawLine(1, 1, width - 1, 1); // b, horizontal + g.drawLine(1, 2, 1, height - 1); // b, vertical + + g.setColor(c); + g.drawLine(2, height - 1, width - 1, height - 1); // c, horizontal + g.drawLine(width - 1, 2, width - 1, height - 2); // c, vertical + + g.setColor(d); + g.drawLine(1, height, width, height); // d, horizontal + g.drawLine(width, 1, width, height - 1); // d, vertical + } + finally + { + g.translate(-x, -y); + g.setColor(oldColor); + } + } +} diff --git a/libjava/classpath/javax/swing/border/Border.java b/libjava/classpath/javax/swing/border/Border.java new file mode 100644 index 000000000..da25832ad --- /dev/null +++ b/libjava/classpath/javax/swing/border/Border.java @@ -0,0 +1,103 @@ +/* Border.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.border; + +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; + + +/** + * An public interface for decorative or spacing borders around a Component. + * + *

To reduce memory consumption, several Components may share a + * single Border instance. {@link javax.swing.BorderFactory} is a + * factory class for producing commonly used shared borders. + * + * @see javax.swing.BorderFactory + * @see EmptyBorder + * @see CompoundBorder + * @see BevelBorder + * @see EtchedBorder + * @see LineBorder + * @see MatteBorder + * @see SoftBevelBorder + * @see TitledBorder + * @see AbstractBorder + * + * @author Ronald Veldema (rveldema@cs.vu.nl) + * @author Michael Koch (konqueror@gmx.de) + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public interface Border +{ + /** + * Paints the border for a given component. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + void paintBorder(Component c, Graphics g, int x, int y, int width, + int height); + + /** + * Measures the width of this border. + * + * @param c the component whose border is to be measured. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge. + */ + Insets getBorderInsets(Component c); + + /** + * Determines whether this border fills every pixel in its area + * when painting. + * + * @return true if the border is fully opaque, or + * false if some pixels of the background + * can shine through the border. + */ + boolean isBorderOpaque(); +} diff --git a/libjava/classpath/javax/swing/border/CompoundBorder.java b/libjava/classpath/javax/swing/border/CompoundBorder.java new file mode 100644 index 000000000..d811150ba --- /dev/null +++ b/libjava/classpath/javax/swing/border/CompoundBorder.java @@ -0,0 +1,255 @@ +/* CompoundBorder.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.border; + +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; + +/** + * A Border that is composed of an interior and an exterior border, + * where the interior border is tightly nested into the exterior. + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class CompoundBorder extends AbstractBorder +{ + /** + * Determined using the serialver tool + * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. + */ + static final long serialVersionUID = 9054540377030555103L; + + /** + * The inside border, which is painted between the bordered + * Component and the outside border. It is valid for + * insideBorder to be null. + */ + protected Border insideBorder; + + /** + * The outside border, which is painted outside both the + * bordered Component and the inside border. It is valid for + * outsideBorder to be null. + */ + protected Border outsideBorder; + + /** + * Constructs a CompoundBorder whose inside and outside borders + * are both null. While this does not really make + * any sense (there exists a class EmptyBorder as well, and not + * every Component needs to have a border at all), the API + * specification requires the existence of this constructor. + * + * @see EmptyBorder + */ + public CompoundBorder() + { + this (null, null); + } + + /** + * Constructs a CompoundBorder with the specified inside and + * outside borders. + * + * @param outsideBorder the outside border, which is painted to the + * outside of both insideBorder and the enclosed + * component. It is acceptable to pass null, in + * which case no outside border is painted. + * + * @param insideBorder the inside border, which is painted to + * between outsideBorder and the enclosed + * component. It is acceptable to pass null, in + * which case no inside border is painted. + */ + public CompoundBorder(Border outsideBorder, Border insideBorder) + { + this.outsideBorder = outsideBorder; + this.insideBorder = insideBorder; + } + + /** + * Determines whether or not this border is opaque. An opaque + * border fills every pixel in its area when painting. Partially + * translucent borders must return false, or ugly + * artifacts can appear on screen. + * + * @return true if both the inside and outside borders + * are opaque, or false otherwise. + */ + public boolean isBorderOpaque() + { + // Although the API specification states that this method + // returns true if both the inside and outside borders are non-null + // and opaque, and false otherwise, a mauve test shows that if both + // the inside or outside borders are null, then true is returned. + if ((insideBorder == null) && (outsideBorder == null)) + return true; + + // A mauve test shows that if the inside border has a null value, + // then true is returned if the outside border is opaque; if the + // outside border has a null value, then true is returned if the + // inside border is opaque; else, true is returned if both the + // inside and outside borders are opaque. + if (insideBorder == null) + return outsideBorder.isBorderOpaque(); + else if (outsideBorder == null) + return insideBorder.isBorderOpaque(); + else + return insideBorder.isBorderOpaque() && outsideBorder.isBorderOpaque(); + } + + /** + * Paints the compound border by first painting the outside border, + * then painting the inside border tightly nested into the outside. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + public void paintBorder(Component c, Graphics g, + int x, int y, int width, int height) + { + // If there is an outside border, paint it and reduce the + // bounding box by its insets. + // + if (outsideBorder != null) + { + Insets outsideInsets; + + outsideBorder.paintBorder(c, g, x, y, width, height); + outsideInsets = outsideBorder.getBorderInsets(c); + + x += outsideInsets.left; + y += outsideInsets.top; + + // Reduce width and height by the respective extent of the + // outside border. + width -= outsideInsets.left + outsideInsets.right; + height -= outsideInsets.top + outsideInsets.bottom; + } + + if (insideBorder != null) + insideBorder.paintBorder(c, g, x, y, width, height); + } + + /** + * Changes the specified insets to the insets of this border, + * which is the sum of the insets of the inside and the outside + * border. + * + * @param c the component in the center of this border. + * @param insets an Insets object for holding the added insets. + * + * @return the insets object. + */ + public Insets getBorderInsets(Component c, Insets insets) + { + Insets borderInsets; + + if (insets == null) + insets = new Insets(0, 0, 0, 0); + else + insets.left = insets.right = insets.top = insets.bottom = 0; + + // If there is an outside border, add it to insets. + if (outsideBorder != null) + { + borderInsets = outsideBorder.getBorderInsets(c); + insets.left += borderInsets.left; + insets.right += borderInsets.right; + insets.top += borderInsets.top; + insets.bottom += borderInsets.bottom; + } + + // If there is an inside border, add it to insets. + if (insideBorder != null) + { + borderInsets = insideBorder.getBorderInsets(c); + insets.left += borderInsets.left; + insets.right += borderInsets.right; + insets.top += borderInsets.top; + insets.bottom += borderInsets.bottom; + } + + return insets; + } + + /** + * Determines the insets of this border, which is the sum of the + * insets of the inside and the outside border. + * + * @param c the component in the center of this border. + */ + public Insets getBorderInsets(Component c) + { + // It is not clear why CompoundBorder does not simply inherit + // the implementation from AbstractBorder. However, we want + // to be compatible with the API specification, which overrides + // the getBorderInsets(Component) method. + return getBorderInsets(c, null); + } + + /** + * Returns the outside border, which is painted outside both the + * bordered Component and the inside border. It is valid for the + * result to be null. + * + * @return The outside border (possibly null). + */ + public Border getOutsideBorder() + { + return outsideBorder; + } + + /** + * Returns the inside border, which is painted between the bordered + * Component and the outside border. It is valid for the result to + * be null. + * + * @return The inside border (possibly null). + */ + public Border getInsideBorder() + { + return insideBorder; + } +} diff --git a/libjava/classpath/javax/swing/border/EmptyBorder.java b/libjava/classpath/javax/swing/border/EmptyBorder.java new file mode 100644 index 000000000..da6651163 --- /dev/null +++ b/libjava/classpath/javax/swing/border/EmptyBorder.java @@ -0,0 +1,223 @@ +/* EmptyBorder.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.border; + +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; + + +/** + * A border for leaving a specifiable number of pixels empty around + * the enclosed component. An EmptyBorder requires some space on each + * edge, but does not perform any drawing. + * + *

[An illustration of EmptyBorder] + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class EmptyBorder extends AbstractBorder +{ + /** + * Determined using the serialver tool + * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. + */ + static final long serialVersionUID = -8116076291731988694L; + + + /** + * The number of pixels required at the left edge. + */ + protected int left; + + + /** + * The number of pixels required at the right edge. + */ + protected int right; + + + /** + * The number of pixels required at the top edge. + */ + protected int top; + + + /** + * The number of pixels required at the bottom edge. + */ + protected int bottom; + + + /** + * Constructs an empty border given the number of pixels required + * on each side. + * + * @param top the number of pixels that the border will need + * for its top edge. + * + * @param left the number of pixels that the border will need + * for its left edge. + * + * @param bottom the number of pixels that the border will need + * for its bottom edge. + * + * @param right the number of pixels that the border will need + * for its right edge. + */ + public EmptyBorder(int top, int left, int bottom, int right) + { + this.top = top; + this.left = left; + this.bottom = bottom; + this.right = right; + } + + + /** + * Constructs an empty border given the number of pixels required + * on each side, passed in an Insets object. + * + * @param borderInsets the Insets for the new border. + */ + public EmptyBorder(Insets borderInsets) + { + this(borderInsets.top, borderInsets.left, + borderInsets.bottom, borderInsets.right); + } + + + /** + * Performs nothing because an EmptyBorder does not paint any + * pixels. While the inherited implementation provided by + * {@link AbstractBorder#paintBorder} is a no-op as well, + * it is overwritten in order to match the API of the Sun + * reference implementation. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + public void paintBorder(Component c, Graphics g, + int x, int y, int width, int height) + { + // Nothing to do here. + } + + + /** + * Measures the width of this border. + * + * @param c the component whose border is to be measured. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets(Component c) + { + return getBorderInsets(c, null); + } + + + /** + * Measures the width of this border, storing the results into a + * pre-existing Insets object. + * + * @param insets an Insets object for holding the result values. + * After invoking this method, the left, + * right, top and + * bottom fields indicate the width of the + * border at the respective edge. + * + * @return the same object that was passed for insets. + * + * @see #getBorderInsets() + */ + public Insets getBorderInsets(Component c, Insets insets) + { + if (insets == null) + insets = new Insets(0, 0, 0, 0); + + insets.left = left; + insets.right = right; + insets.top = top; + insets.bottom = bottom; + return insets; + } + + + /** + * Measures the width of this border. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets() + { + return getBorderInsets(null, null); + } + + + /** + * Determines whether this border fills every pixel in its area + * when painting. Since an empty border does not paint any pixels + * whatsoever, the result is false. + * + * @return false. + */ + public boolean isBorderOpaque() + { + /* The inherited implementation of AbstractBorder.isBorderOpaque() + * would also return false. It is not clear why this is overriden + * in the Sun implementation, at least not from just reading the + * JavaDoc. + */ + return false; + } +} diff --git a/libjava/classpath/javax/swing/border/EtchedBorder.java b/libjava/classpath/javax/swing/border/EtchedBorder.java new file mode 100644 index 000000000..e9ee9e218 --- /dev/null +++ b/libjava/classpath/javax/swing/border/EtchedBorder.java @@ -0,0 +1,414 @@ +/* EtchedBorder.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.border; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; + + +/** + * A border that looks like an engraving etched into the background + * surface, or (in its raised variant) coming out of the surface + * plane. Using different constructors, it is possible to either + * explicitly specify the border colors, or to let the colors derive + * from the background color of the enclosed Component. + * + *

[An illustration of the two EtchedBorder variants] + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class EtchedBorder extends AbstractBorder +{ + /** + * Determined using the serialver tool + * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. + */ + static final long serialVersionUID = 4001244046866360638L; + + + /** + * Indicates that the border appears as coming out of the + * background. + */ + public static final int RAISED = 0; + + + /** + * Indicates that the border appears as engraved into the + * background. + */ + public static final int LOWERED = 1; + + + /** + * The type of this EtchedBorder, which is either {@link #RAISED} + * or {@link #LOWERED}. + */ + protected int etchType; + + + /** + * The highlight color, or null to indicate that the + * color shall be derived from the background of the enclosed + * component. + */ + protected Color highlight; + + + /** + * The shadow color, or null to indicate that the + * color shall be derived from the background of the enclosed + * component. + */ + protected Color shadow; + + + /** + * Constructs a lowered EtchedBorder. The colors will be derived + * from the background color of the enclosed Component when the + * border gets painted. + */ + public EtchedBorder() + { + this(LOWERED); + } + + + /** + * Constructs an EtchedBorder with the specified appearance. The + * colors will be derived from the background color of the enclosed + * Component when the border gets painted. + * + *

[An illustration of the two EtchedBorder variants] + * + * @param etchType the desired appearance of the border. The value + * must be either {@link #RAISED} or {@link #LOWERED}. + * + * @throws IllegalArgumentException if etchType has + * an unsupported value. + */ + public EtchedBorder(int etchType) + { + if ((etchType != RAISED) && (etchType != LOWERED)) + throw new IllegalArgumentException(); + + this.etchType = etchType; + + /* The highlight and shadow fields already have a null value + * when the constructor gets called, so there is no need to + * assign a value here. + */ + } + + + /** + * Constructs a lowered EtchedBorder, explicitly selecting the + * colors that will be used for highlight and shadow. + * + * @param highlight the color that will be used for painting + * the highlight part of the border. + * + * @param shadow the color that will be used for painting + * the shadow part of the border. + * + * @see #EtchedBorder(int, Color, Color) + */ + public EtchedBorder(Color highlight, Color shadow) + { + this(LOWERED, highlight, shadow); + } + + + /** + * Constructs an EtchedBorder with the specified appearance, + * explicitly selecting the colors that will be used for + * highlight and shadow. + * + *

[An illustration that shows which pixels get painted
+   * in what color] + * + * @param etchType the desired appearance of the border. The value + * must be either {@link #RAISED} or {@link #LOWERED}. + * + * @param highlight the color that will be used for painting + * the highlight part of the border. + * + * @param shadow the color that will be used for painting + * the shadow part of the border. + * + * @throws IllegalArgumentException if etchType has + * an unsupported value. + */ + public EtchedBorder(int etchType, Color highlight, Color shadow) + { + this(etchType); // Checks the validity of the value. + this.highlight = highlight; + this.shadow = shadow; + } + + + /** + * Paints the border for a given component. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + public void paintBorder(Component c, Graphics g, int x, int y, int width, + int height) + { + switch (etchType) + { + case RAISED: + paintEtchedBorder(g, x, y, width, height, + getHighlightColor(c), getShadowColor(c)); + break; + + case LOWERED: + paintEtchedBorder(g, x, y, width, height, + getShadowColor(c), getHighlightColor(c)); + break; + } + } + + + /** + * Measures the width of this border. + * + * @param c the component whose border is to be measured. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets(Component c) + { + return new Insets(2, 2, 2, 2); + } + + + /** + * Measures the width of this border, storing the results into a + * pre-existing Insets object. + * + * @param insets an Insets object for holding the result values. + * After invoking this method, the left, + * right, top and + * bottom fields indicate the width of the + * border at the respective edge. + * + * @return the same object that was passed for insets. + * + * @see #getBorderInsets(Component) + */ + public Insets getBorderInsets(Component c, Insets insets) + { + insets.left = insets.right = insets.top = insets.bottom = 2; + return insets; + } + + + /** + * Determines whether this border fills every pixel in its area + * when painting. + * + *

If the border colors are derived from the background color of + * the enclosed component, the result is true because + * the derivation method always returns opaque colors. Otherwise, + * the result depends on the opacity of the individual colors. + * + * @return true if the border is fully opaque, or + * false if some pixels of the background + * can shine through the border. + */ + public boolean isBorderOpaque() + { + // If the colors are to be derived from the enclosed Component's + // background color, the border is guaranteed to be fully opaque + // because Color.brighten() and Color.darken() always return an + // opaque color. + return + ((highlight == null) || (highlight.getAlpha() == 255)) + && ((shadow == null) || (shadow.getAlpha() == 255)); + } + + /** + * Returns the appearance of this EtchedBorder, which is either + * {@link #RAISED} or {@link #LOWERED}. + * + * @return The type ({@link #RAISED} or {@link #LOWERED}). + */ + public int getEtchType() + { + return etchType; + } + + + /** + * Determines the color that will be used for highlighted parts when + * painting the border around a given component. If a highlight + * color has been specified upon constructing the border, that color + * is returned. Otherwise, the background color of the enclosed + * component is brightened. + * + * @param c the component enclosed by this border. + * + * @return The color. + * + * @see java.awt.Component#getBackground() + * @see java.awt.Color#brighter() + */ + public Color getHighlightColor(Component c) + { + if (highlight != null) + return highlight; + else + return c.getBackground().brighter(); + } + + /** + * Returns the color that will be used for highlighted parts when + * painting the border, or null if that color will be + * derived from the background of the enclosed Component. + * + * @return The highlight color (possibly null). + */ + public Color getHighlightColor() + { + return highlight; + } + + + /** + * Determines the color that will be used for shadowed parts when + * painting the border around a given component. If a shadow color + * has been specified upon constructing the border, that color is + * returned. Otherwise, the background color of the enclosed + * component is darkened. + * + * @param c the component enclosed by this border. + * + * @return The shadow color. + * + * @see java.awt.Component#getBackground() + * @see java.awt.Color#darker() + */ + public Color getShadowColor(Component c) + { + if (shadow != null) + return shadow; + else + return c.getBackground().darker(); + } + + + /** + * Returns the color that will be used for shadowed parts when + * painting the border, or null if that color will be + * derived from the background of the enclosed Component. + * + * @return The shadow color (possibly null). + */ + public Color getShadowColor() + { + return shadow; + } + + + /** + * Paints a two-pixel etching in two colors. + * + *

+   * +++++++++++.
+   * +.........+.    + = color a
+   * +.        +.    . = color b
+   * +.        +.
+   * +++++++++++.
+   * ............
+ * + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + * @param a one of the two colors. + * @param b the second of the two colors. + */ + private static void paintEtchedBorder(Graphics g, int x, int y, int width, + int height, Color a, Color b) + { + Color oldColor; + + oldColor = g.getColor(); + g.translate(x, y); + width = width - 1; + height = height - 1; + + try + { + // To understand this code, it might be helpful to look at the + // images that are included with the JavaDoc. They are located + // in the "doc-files" subdirectory. EtchedBorder-2.png might + // be especially informative. + g.setColor(a); + g.drawRect(0, 0, width - 1, height - 1); + + g.setColor(b); + g.drawLine(1, 1, width - 2, 1); // top edge + g.drawLine(1, 2, 1, height - 2); // left edge + g.drawLine(0, height, width, height); // bottom edge + g.drawLine(width, 0, width, height - 1); // right edge + } + finally + { + g.translate(-x, -y); + g.setColor(oldColor); + } + } +} diff --git a/libjava/classpath/javax/swing/border/LineBorder.java b/libjava/classpath/javax/swing/border/LineBorder.java new file mode 100644 index 000000000..e78bbee3b --- /dev/null +++ b/libjava/classpath/javax/swing/border/LineBorder.java @@ -0,0 +1,347 @@ +/* LineBorder.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.border; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; + + +/** + * A border that consists of a line whose thickness and color can be + * specified. There also is a variant with rounded corners. + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class LineBorder extends AbstractBorder +{ + /** + * Determined using the serialver tool + * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. + */ + static final long serialVersionUID = -787563427772288970L; + + + /** + * A shared instance of a black, one pixel thick, plain LineBorder. + * The singleton object is lazily created by {@link + * #createBlackLineBorder()} upon its first invocation. + */ + private static LineBorder blackLineBorder; + + + /** + * A shared instance of a gray, one pixel thick, plain LineBorder. + * The singleton object is lazily created by {@link + * #createGrayLineBorder()} upon its first invocation. + */ + private static LineBorder grayLineBorder; + + + /** + * The width of the line in pixels. + */ + protected int thickness; + + + /** + * The color of the line. + */ + protected Color lineColor; + + + /** + * Indicates whether the line is drawn with rounded corners + * (true) or not ((false). + */ + protected boolean roundedCorners; + + + /** + * Constructs a LineBorder given its color. The border will be one + * pixel thick and have plain corners. + * + * @param color the color for drawing the border. + * + * @see #LineBorder(java.awt.Color, int, boolean) + */ + public LineBorder(Color color) + { + this(color, /* thickness */ 1, /* roundedCorners */ false); + } + + + /** + * Constructs a LineBorder given its color and thickness. The + * border will have plain corners. + * + * @param color the color for drawing the border. + * @param thickness the width of the line in pixels. + * + * @see #LineBorder(java.awt.Color, int, boolean) + */ + public LineBorder(Color color, int thickness) + { + this (color, thickness, /* roundedCorners */ false); + } + + + /** + * Constructs a LineBorder given its color, thickness, and whether + * it has rounded corners. + * + *

[An illustration of two LineBorders] + * + *

Note that the enlarged view in the right-hand picture shows + * that the implementation draws one more pixel than specified, + * provided that roundedCorders is true + * and anti-aliasing is turned on while painting. While this might + * be considered a bug, the Sun reference implementation (at least + * JDK 1.3.1 on Apple MacOS X 10.1.5) can be observed to fill + * exactly the same pixels as shown above. The GNU Classpath + * LineBorder replicates the observed behavior of the Sun + * implementation. + * + * @param color the color for drawing the border. + * @param thickness the width of the line in pixels. + * @param roundedCorners true for rounded corners, + * false for plain corners. + * + * @since 1.3 + */ + // For the bug mentioned in the JavaDoc, please see also the comment + // in the paintBorder method below. + // + public LineBorder(Color color, int thickness, boolean roundedCorners) + { + if ((color == null) || (thickness < 0)) + throw new IllegalArgumentException(); + + this.lineColor = color; + this.thickness = thickness; + this.roundedCorners = roundedCorners; + } + + + /** + * Returns a black, one pixel thick, plain {@link LineBorder}. The method + * may always return the same (singleton) {@link LineBorder} instance. + * + * @return The border. + */ + public static Border createBlackLineBorder() + { + /* Swing is not designed to be thread-safe, so there is no + * need to synchronize the access to the global variable. + */ + if (blackLineBorder == null) + blackLineBorder = new LineBorder(Color.black); + + return blackLineBorder; + } + + + /** + * Returns a gray, one pixel thick, plain {@link LineBorder}. The method + * may always return the same (singleton) {@link LineBorder} instance. + * + * @return The border. + */ + public static Border createGrayLineBorder() + { + /* Swing is not designed to be thread-safe, so there is no + * need to synchronize the access to the global variable. + */ + if (grayLineBorder == null) + grayLineBorder = new LineBorder(Color.gray); + + return grayLineBorder; + } + + + /** + * Paints the line border around a given Component. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + public void paintBorder(Component c, Graphics g, + int x, int y, int width, int height) + { + Color oldColor = g.getColor(); + + try + { + g.setColor(lineColor); + + // If width and height were not adjusted, the border would + // appear one pixel too large in both directions. + width -= 1; + height -= 1; + + // Blurred, too large appearance + // ----------------------------- + // While Java 2D has introduced line strokes of arbitrary width, + // it seems desirable to keep this code independent of Java 2D. + // Therefore, multiple nested rectangles (or rounded rectangles) + // are drawn in order to simulate a line whose thickness is + // greater than one pixel. + // + // This hack causes a blurred appearance when anti-aliasing is + // on. Interestingly enough, though, the Sun JDK 1.3.1 (at least + // on MacOS X 10.1.5) shows exactly the same appearance under + // this condition. It thus seems likely that Sun does the same + // hack for simulating thick lines. For this reason, the + // blurred appearance seems acceptable -- especially since GNU + // Classpath tries to be compatible with the Sun reference + // implementation. + for (int i = 0; i < thickness; i++) + { + if (roundedCorners) + g.drawRoundRect(x, y, width, height, thickness, thickness); + else + g.drawRect(x, y, width, height); + + x += 1; + y += 1; + width -= 2; + height -= 2; + } + } + finally + { + g.setColor(oldColor); + } + } + + + /** + * Measures the width of this border. + * + * @param c the component whose border is to be measured. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge, which is the + * thickness of the line. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets(Component c) + { + return new Insets(thickness, thickness, thickness, thickness); + } + + + /** + * Measures the width of this border, storing the results into a + * pre-existing Insets object. + * + * @param insets an Insets object for holding the result values. + * After invoking this method, the left, + * right, top and + * bottom fields indicate the width of the + * border at the respective edge, which is the thickness + * of the line. + * + * @return the same object that was passed for insets. + * + * @see #getBorderInsets(Component) + */ + public Insets getBorderInsets(Component c, Insets insets) + { + insets.left = insets.right = insets.top = insets.bottom = thickness; + return insets; + } + + + /** + * Returns the color of the line. + * + * @return The line color (never null). + */ + public Color getLineColor() + { + return lineColor; + } + + + /** + * Returns the thickness of the line in pixels. + * + * @return The line thickness (in pixels). + */ + public int getThickness() + { + return thickness; + } + + + /** + * Returns whether this LineBorder os drawm with rounded + * or with plain corners. + * + * @return true if the corners are rounded, + * false if the corners are plain. + */ + public boolean getRoundedCorners() + { + return roundedCorners; + } + + + /** + * Determines whether this border fills every pixel in its area + * when painting. + * + * @return true if the corners are plain and the line + * color is fully opaque; false if the corners + * are rounded or the line color is partially transparent. + */ + public boolean isBorderOpaque() + { + return (!roundedCorners) && (lineColor.getAlpha() == 255); + } +} diff --git a/libjava/classpath/javax/swing/border/MatteBorder.java b/libjava/classpath/javax/swing/border/MatteBorder.java new file mode 100644 index 000000000..c0c2d7760 --- /dev/null +++ b/libjava/classpath/javax/swing/border/MatteBorder.java @@ -0,0 +1,407 @@ +/* MatteBorder.java -- + Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.border; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; + +import javax.swing.Icon; + +/** + * A border that is filled with either a solid color or with repeated + * icon tiles. + * + *

[Two MatteBorders] + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class MatteBorder extends EmptyBorder +{ + /** + * Determined using the serialver tool + * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. + */ + static final long serialVersionUID = 4422248989617298224L; + + + /** + * The color that is used for filling the border, or + * null if the border is filled with repetitions of a + * tile icon. + * + * @see #tileIcon + */ + protected Color color; + + + /** + * The icon is used for filling the border with a tile, or + * null if the border is filled with a solid + * color. + * + * @see #color + */ + protected Icon tileIcon; + + + /** + * Constructs a MatteBorder given the width on each side + * and a fill color. + * + *

[A picture of a MatteBorder made by this constructor] + * + * @param top the width of the border at its top edge. + * @param left the width of the border at its left edge. + * @param bottom the width of the border at its bottom edge. + * @param right the width of the border at its right edge. + * @param matteColor the color for filling the border. + */ + public MatteBorder(int top, int left, int bottom, int right, + Color matteColor) + { + super(top, left, bottom, right); + + if (matteColor == null) + throw new IllegalArgumentException(); + + this.color = matteColor; + } + + + /** + * Constructs a MatteBorder given its insets and fill color. + * + *

[A picture of a MatteBorder made by this constructor] + * + * @param borderInsets an Insets object whose top, + * left, bottom and right + * fields indicate the with of the border at the respective + * edge. + * + * @param matteColor the color for filling the border. + */ + public MatteBorder(Insets borderInsets, Color matteColor) + { + this(borderInsets.top, borderInsets.left, + borderInsets.bottom, borderInsets.right, + matteColor); + } + + + /** + * Constructs a MatteBorder given the width on each side + * and an icon for tiling the border area. + * + *

[A picture of a MatteBorder made by this constructor] + * + * @param top the width of the border at its top edge. + * @param left the width of the border at its left edge. + * @param bottom the width of the border at its bottom edge. + * @param right the width of the border at its right edge. + * @param tileIcon an icon for tiling the border area. + */ + public MatteBorder(int top, int left, int bottom, int right, + Icon tileIcon) + { + super(top, left, bottom, right); + + this.tileIcon = tileIcon; + } + + + /** + * Constructs a MatteBorder given its insets and an icon + * for tiling the border area. + * + *

[A picture of a MatteBorder made by this constructor] + * + * @param borderInsets an Insets object whose top, + * left, bottom and right + * fields indicate the with of the border at the respective + * edge. + * + * @param tileIcon an icon for tiling the border area. + */ + public MatteBorder(Insets borderInsets, Icon tileIcon) + { + this(borderInsets.top, borderInsets.left, + borderInsets.bottom, borderInsets.right, + tileIcon); + } + + + /** + * Constructs a MatteBorder given an icon for tiling the + * border area. The icon width is used for the border insets + * at the left and right edge, the icon height for the top and + * bottom edge. + * + *

[A picture of a MatteBorder made by this constructor] + * + * @param tileIcon an icon for tiling the border area. + */ + public MatteBorder(Icon tileIcon) + { + this(-1, -1, -1, -1, tileIcon); + } + + + /** + * Paints the border for a given component. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + public void paintBorder(Component c, Graphics g, + int x, int y, int width, int height) + { + Insets i = getBorderInsets(); + paintEdge(c, g, x, y, width, i.top, 0, 0); // top edge + paintEdge(c, g, x, y + height - i.bottom, // bottom edge + width, i.bottom, + 0, height - i.bottom); + paintEdge(c, g, x, y + i.top, // left edge + i.left, height - i.top, + 0, i.top); + paintEdge(c, g, x + width - i.right, y + i.top, // right edge + i.right, height - i.bottom, + width - i.right, i.top); + } + + + /** + * Measures the width of this border. + * + * @param c the component whose border is to be measured. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets(Component c) + { + /* There is no obvious reason for overriding this method, but we + * try to have exactly the same API as the Sun reference + * implementation. + */ + return this.getBorderInsets(c, null); + } + + + /** + * Measures the width of this border, storing the results into a + * pre-existing Insets object. + * + * @param insets an Insets object for holding the result values. + * After invoking this method, the left, + * right, top and + * bottom fields indicate the width of the + * border at the respective edge. + * + * @return the same object that was passed for insets. + * + * @see #getBorderInsets() + */ + public Insets getBorderInsets(Component c, Insets insets) + { + if (insets == null) + insets = new Insets(0, 0, 0, 0); + + if ((tileIcon != null) + && (top < 0) && (left < 0) + && (right < 0) && (bottom < 0)) + { + insets.left = insets.right = tileIcon.getIconWidth(); + insets.top = insets.bottom = tileIcon.getIconHeight(); + return insets; + } + + /* Copy top, left, bottom and right into the respective + * field of insets. + */ + return super.getBorderInsets(c, insets); + } + + + /** + * Measures the width of this border. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets() + { + /* The inherited implementation of EmptyBorder.isBorderOpaque() + * would do the same. It is not clear why this is overriden in the + * Sun implementation, at least not from just reading the JavaDoc. + */ + return this.getBorderInsets(null, null); + } + + + /** + * Returns the color that is used for filling the border, or + * null if the border is filled with repetitions of a + * tile icon. + * + * @return The color (possibly null). + */ + public Color getMatteColor() + { + return color; + } + + + /** + * Returns the icon is used for tiling the border, or + * null if the border is filled with a color instead of + * an icon. + * + * @return The icon (possibly null). + */ + public Icon getTileIcon() + { + return tileIcon; + } + + + /** + * Determines whether this border fills every pixel in its area + * when painting. + * + * @return true if the border is filled with an + * opaque color; false if it is filled with + * a semi-transparent color or with an icon. + */ + public boolean isBorderOpaque() + { + return (color != null) && (color.getAlpha() == 255); + } + + + /** + * Paints a rectangular area of the border. This private helper + * method is called once for each of the border edges + * by {@link #paintBorder}. + * + * @param c the component whose border is being painted. + * @param g the graphics for painting. + * @param x the horizontal position of the rectangular area. + * @param y the vertical position of the rectangular area. + * @param width the width of the rectangular area. + * @param height the height of the rectangular area. + * @param dx the x displacement for repeating the tile. + * @param dy the y displacement for repeating the tile. + */ + private void paintEdge(Component c, Graphics g, + int x, int y, int width, int height, + int dx, int dy) + { + Color oldColor; + int iconWidth, iconHeight; + Graphics clipped; + + if ((width <= 0) || (height <= 0)) + return; + + /* Paint a colored rectangle if desired. */ + if (color != null) + { + oldColor = g.getColor(); + try + { + g.setColor(color); + g.fillRect(x, y, width, height); + } + finally + { + g.setColor(oldColor); + } + return; + } + + // If this border has no icon end painting here. + if (tileIcon == null) + return; + + /* Determine the width and height of the icon. Some icons return + * -1 if it is an image whose dimensions have not yet been + * retrieved. There is not much we can do about this, but we + * should at least avoid entering the paint loop below + * with negative increments. + */ + iconWidth = tileIcon.getIconWidth(); + iconHeight = tileIcon.getIconHeight(); + if ((iconWidth <= 0) || (iconHeight <= 0)) + return; + + dx = dx % iconWidth; + dy = dy % iconHeight; + + clipped = g.create(); + try + { + clipped.setClip(x, y, width, height); + for (int ty = y - dy; ty < y + height; ty += iconHeight) + for (int tx = x - dx; tx < x + width; tx += iconWidth) + tileIcon.paintIcon(c, clipped, tx, ty); + } + finally + { + clipped.dispose(); + } + } +} diff --git a/libjava/classpath/javax/swing/border/SoftBevelBorder.java b/libjava/classpath/javax/swing/border/SoftBevelBorder.java new file mode 100644 index 000000000..c0c9ae811 --- /dev/null +++ b/libjava/classpath/javax/swing/border/SoftBevelBorder.java @@ -0,0 +1,327 @@ +/* SoftBevelBorder.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.swing.border; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; + + +/** + * A rectangular, three pixel thick border that looks like a BevelBorder + * with slightly softened corners. + * + *

Like BevelBorder, SoftBevelBorder has a highlight and a shadow + * color. In the raised variant, the highlight color is used for the + * top and left edges, and the shadow color is used for the bottom and + * right edge. In the lowered variant, color usage is reversed. For + * an image, see the documentation of the individual constructors. + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class SoftBevelBorder extends BevelBorder +{ + /** + * Determined using the serialver tool + * of Sun JDK 1.4.1_01 on GNU/Linux 2.4.20. Interestingly, + * the Apple/Sun JDK 1.3.1 on MacOS X 10.1.5 gives a different + * value, namely -6658357140774549493L. + */ + static final long serialVersionUID = 5248789787305979975L; + + + /** + * Constructs a SoftBevelBorder whose colors will be derived from the + * background of the enclosed component. The background color is + * retrieved each time the border is painted, so a SoftBevelBorder + * constructed by this method will automatically reflect a change + * to the component’s background color. + * + *

[An illustration showing raised and lowered SoftBevelBorders] + * + * @param bevelType the desired appearance of the border. The value + * must be either {@link BevelBorder#RAISED} + * or {@link BevelBorder#LOWERED}. + * + * @throws IllegalArgumentException if bevelType has + * an unsupported value. + */ + public SoftBevelBorder(int bevelType) + { + super(bevelType); + } + + + /** + * Constructs a SoftBevelBorder given its appearance type and two + * colors for its highlight and shadow. + * + *

[An illustration showing SoftBevelBorders that were
+   * constructed with this method] + * + * @param bevelType the desired appearance of the border. The value + * must be either {@link BevelBorder#RAISED} or {@link + * BevelBorder#LOWERED}. + * + * @param highlight the color that will be used for the inner side + * of the highlighted edges (top and left if if + * bevelType is {@link BevelBorder#RAISED}; + * bottom and right otherwise). The color for the outer side + * is a brightened version of this color. + * + * @param shadow the color that will be used for the outer side of + * the shadowed edges (bottom and right if + * bevelType is {@link BevelBorder#RAISED}; top + * and left otherwise). The color for the inner side is a + * brightened version of this color. + * + * @throws IllegalArgumentException if bevelType has an + * unsupported value. + * + * @throws NullPointerException if highlight or + * shadow is null. + * + * @see java.awt.Color#brighter() + */ + public SoftBevelBorder(int bevelType, Color highlight, Color shadow) + { + this(bevelType, + /* highlightOuter */ highlight.brighter(), + /* highlightInner */ highlight, + /* shadowOuter */ shadow, + /* shadowInner */ shadow.brighter()); + } + + + /** + * Constructs a SoftBevelBorder given its appearance type and all + * colors. + * + *

[An illustration showing SoftBevelBorders that were
+   * constructed with this method] + * + * @param bevelType the desired appearance of the border. The value + * must be either {@link BevelBorder#RAISED} or {@link + * BevelBorder#LOWERED}. + * + * @param highlightOuter the color that will be used for the outer + * side of the highlighted edges (top and left if + * bevelType is {@link BevelBorder#RAISED}; + * bottom and right otherwise). + * + * @param highlightInner the color that will be used for the inner + * side of the highlighted edges. + * + * @param shadowOuter the color that will be used for the outer side + * of the shadowed edges (bottom and right if + * bevelType is {@link BevelBorder#RAISED}; top + * and left otherwise). + * + * @param shadowInner the color that will be used for the inner + * side of the shadowed edges. + * + * @throws IllegalArgumentException if bevelType has + * an unsupported value. + * + * @throws NullPointerException if one of the passed colors + * is null. + */ + public SoftBevelBorder(int bevelType, + Color highlightOuter, Color highlightInner, + Color shadowOuter, Color shadowInner) + { + super(bevelType, + highlightOuter, highlightInner, + shadowOuter, shadowInner); + } + + + /** + * Paints the border for a given component. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + public void paintBorder(Component c, Graphics g, + int x, int y, int width, int height) + { + switch (bevelType) + { + case RAISED: + paintSoftBevel(g, x, y, width, height, + getHighlightOuterColor(c), getHighlightInnerColor(c), + getShadowInnerColor(c), getShadowOuterColor(c)); + break; + + case LOWERED: + paintSoftBevel(g, x, y, width, height, + getShadowOuterColor(c), getShadowInnerColor(c), + getHighlightInnerColor(c), getHighlightOuterColor(c)); + break; + } + } + + + /** + * Measures the width of this border. + * + * @param c the component whose border is to be measured. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets(Component c) + { + return new Insets(3, 3, 3, 3); + } + + + /** + * Measures the width of this border, storing the results into a + * pre-existing Insets object. + * + * @param insets an Insets object for holding the result values. + * After invoking this method, the left, + * right, top and + * bottom fields indicate the width of the + * border at the respective edge. + * + * @return the same object that was passed for insets. + * + * @see #getBorderInsets(Component) + */ + public Insets getBorderInsets(Component c, Insets insets) + { + insets.left = insets.right = insets.top = insets.bottom = 3; + return insets; + } + + + /** + * Determines whether this border fills every pixel in its area + * when painting. + * + *

The enlarged view (see documentation for constructors) shows + * that a SoftBevelBorder does not paint all pixels. Therefore, + * this method always returns false. + * + * @return false. + */ + public boolean isBorderOpaque() + { + return false; + } + + + /** + * Paints a soft bevel in four colors. + * + *

+   * +++++++++++.
+   * ++.........#    + = color a
+   * +..        #    . = color b
+   * +.         #    X = color c
+   * ..        X#    # = color d
+   * . ##########
+ * + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + * @param a the color for the outer side of the top and left edges. + * @param b the color for the inner side of the top and left edges. + * @param c the color for the inner side of the bottom and right edges. + * @param d the color for the outer side of the bottom and right edges. + */ + private static void paintSoftBevel(Graphics g, + int x, int y, int width, int height, + Color a, Color b, Color c, Color d) + { + Color oldColor; + + oldColor = g.getColor(); + g.translate(x, y); + width = width - 1; + height = height - 1; + + try + { + /* To understand this code, it might be helpful to look at the + * images that are included with the JavaDoc, especially + * SoftBevelBorder-3.png. They are located in the "doc-files" + * subdirectory. + */ + g.setColor(a); + g.drawLine(0, 0, width - 1, 0); // a, horizontal + g.drawLine(0, 1, 2, 1); // a, horizontal + g.drawLine(0, 2, 0, height - 1); // a, vertical + + g.setColor(b); + g.drawLine(width, 0, width, 0); // b, horizontal + g.drawLine(2, 1, width - 1, 1); // b, horizontal + g.drawLine(1, 2, 2, 2); // b, horizontal + g.drawLine(1, 3, 1, height - 1); // b, vertical + g.drawLine(0, height - 1, 0, height); // b, vertical + + g.setColor(c); + g.drawLine(width - 1, height - 1, // c, one pixel + width - 1, height - 1); + + g.setColor(d); + g.drawLine(2, height, width, height); // d, horizontal + g.drawLine(width, 2, width, height - 1); // d, vertical + } + finally + { + g.translate(-x, -y); + g.setColor(oldColor); + } + } +} diff --git a/libjava/classpath/javax/swing/border/TitledBorder.java b/libjava/classpath/javax/swing/border/TitledBorder.java new file mode 100644 index 000000000..4d4f3af7d --- /dev/null +++ b/libjava/classpath/javax/swing/border/TitledBorder.java @@ -0,0 +1,1078 @@ +/* TitledBorder.java -- + Copyright (C) 2003, 2004, 2005, 2006, Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.border; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; + +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + + +/** + * A border that paints a title on top of another border. + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class TitledBorder extends AbstractBorder +{ + /** + * A value for the titlePosition property that vertically + * positions the title text at the default vertical position, which + * is in the middle of the top line of the border. + * + * @see #getTitlePosition() + * @see #setTitlePosition(int) + */ + public static final int DEFAULT_POSITION = 0; + + + /** + * A value for the titlePosition property that vertically + * positions the title text above the top line of the border. + * + * @see #getTitlePosition() + * @see #setTitlePosition(int) + */ + public static final int ABOVE_TOP = 1; + + + /** + * A value for the titlePosition property that vertically + * positions the title text at the middle of the top line + * of the border. + * + * @see #getTitlePosition() + * @see #setTitlePosition(int) + */ + public static final int TOP = 2; + + + /** + * A value for the titlePosition property that vertically + * positions the title text below the top line of the border. + * + * @see #getTitlePosition() + * @see #setTitlePosition(int) + */ + public static final int BELOW_TOP = 3; + + + /** + * A value for the titlePosition property that vertically + * positions the title text above the bottom line of the border. + * + * @see #getTitlePosition() + * @see #setTitlePosition(int) + */ + public static final int ABOVE_BOTTOM = 4; + + + /** + * A value for the titlePosition property that vertically + * positions the title text at the center of the bottom line + * of the border. + * + * @see #getTitlePosition() + * @see #setTitlePosition(int) + */ + public static final int BOTTOM = 5; + + + /** + * A value for the titlePosition property that vertically + * positions the title text below the bottom line of the border. + * + * @see #getTitlePosition() + * @see #setTitlePosition(int) + */ + public static final int BELOW_BOTTOM = 6; + + + /** + * A value for the titleJustification property that + * horizontally aligns the title text with either the left or the + * right edge of the border, depending on the orientation of the + * component nested into the border. If the component orientation + * is left-to-right, the title text is aligned with the left edge; + * otherwise, it is aligned with the right edge. This is the same + * behavior as with {@link #LEADING}. + * + * @see #getTitleJustification() + * @see #setTitleJustification(int) + * @see java.awt.ComponentOrientation#isLeftToRight() + */ + public static final int DEFAULT_JUSTIFICATION = 0; + + + /** + * A value for the titleJustification property that + * horizontally aligns the title text with the left-hand edge of + * the border. + * + * @see #getTitleJustification() + * @see #setTitleJustification(int) + */ + public static final int LEFT = 1; + + + /** + * A value for the titleJustification property that + * horizontally aligns the title text with the center of the border. + * + * @see #getTitleJustification() + * @see #setTitleJustification(int) + */ + public static final int CENTER = 2; + + + /** + * A value for the titleJustification property that + * horizontally aligns the title text with the right-hand edge of + * the border. + * + * @see #getTitleJustification() + * @see #setTitleJustification(int) + */ + public static final int RIGHT = 3; + + + /** + * A value for the titleJustification property that + * horizontally aligns the title text with either the left or the + * right edge of the border, depending on the orientation of the + * component nested into the border. If the component orientation + * is left-to-right, the title text is aligned with the left edge; + * otherwise, it is aligned with the right edge. This is the same + * behavior as with {@link #DEFAULT_JUSTIFICATION}. + * + * @see #getTitleJustification() + * @see #setTitleJustification(int) + * @see java.awt.ComponentOrientation#isLeftToRight() + */ + public static final int LEADING = 4; + + + /** + * A value for the titleJustification property that + * horizontally aligns the title text with either the right or the + * left edge of the border, depending on the orientation of the + * component nested into the border. If the component orientation + * is left-to-right, the title text is aligned with the right edge; + * otherwise, it is aligned with the left edge. + * + * @see #getTitleJustification() + * @see #setTitleJustification(int) + * @see java.awt.ComponentOrientation#isLeftToRight() + */ + public static final int TRAILING = 5; + + + /** + * The number of pixels between the inside of {@link #border} + * and the bordered component. + */ + protected static final int EDGE_SPACING = 2; + + + /** + * The number of pixels between the outside of this TitledBorder + * and the beginning (if left-aligned) or end (if right-aligned) + * of the title text. + */ + protected static final int TEXT_INSET_H = 5; + + + /** + * The number of pixels between the title text and {@link #border}. + * This value is only relevant if the title text does not intersect + * {@link #border}. No intersection occurs if {@link #titlePosition} + * is one of {@link #ABOVE_TOP}, {@link #BELOW_TOP}, {@link #ABOVE_BOTTOM}, + * or {@link #BELOW_BOTTOM}. + */ + protected static final int TEXT_SPACING = 2; + + + /** + * Determined using the serialver tool of Apple/Sun JDK 1.3.1 + * on MacOS X 10.1.5. + */ + static final long serialVersionUID = 8012999415147721601L; + + + /** + * The title, or null to display no title. + */ + protected String title; + + + /** + * The border underneath the title. If this value is + * null, the border will be retrieved from the {@link + * javax.swing.UIManager}’s defaults table using the key + * TitledBorder.border. + */ + protected Border border; + + + /** + * The vertical position of the title text relative to the border, + * which is one of {@link #ABOVE_TOP}, {@link #TOP}, {@link + * #BELOW_TOP}, {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link + * #BELOW_BOTTOM}, or {@link #DEFAULT_POSITION}. + */ + protected int titlePosition; + + + /** + * The horizontal alignment of the title text in relation to the + * border, which is one of {@link #LEFT}, {@link #CENTER}, {@link + * #RIGHT}, {@link #LEADING}, {@link #TRAILING}, or {@link + * #DEFAULT_JUSTIFICATION}. + */ + protected int titleJustification; + + + /** + * The font for displaying the title text. If this value is + * null, the font will be retrieved from the {@link + * javax.swing.UIManager}’s defaults table using the key + * TitledBorder.font. + */ + protected Font titleFont; + + + /** + * The color for displaying the title text. If this value is + * null, the color will be retrieved from the {@link + * javax.swing.UIManager}’s defaults table using the key + * TitledBorder.titleColor. + */ + protected Color titleColor; + + + /** + * Constructs a TitledBorder given the text of its title. + * + * @param title the title text, or null to use no title text. + */ + public TitledBorder(String title) + { + this(/* border */ null, + title, LEADING, TOP, + /* titleFont */ null, /* titleColor */ null); + } + + + /** + * Constructs an initially untitled TitledBorder given another border. + * + * @param border the border underneath the title, or null + * to use a default from the current look and feel. + */ + public TitledBorder(Border border) + { + this(border, /* title */ "", LEADING, TOP, + /* titleFont */ null, /* titleColor */ null); + } + + + /** + * Constructs a TitledBorder given its border and title text. + * + * @param border the border underneath the title, or null + * to use a default from the current look and feel. + * + * @param title the title text, or null to use no title + * text. + */ + public TitledBorder(Border border, String title) + { + this(border, title, LEADING, TOP, + /* titleFont */ null, /* titleColor */ null); + } + + + /** + * Constructs a TitledBorder given its border, title text, horizontal + * alignment, and vertical position. + * + * @param border the border underneath the title, or null + * to use a default from the current look and feel. + * + * @param title the title text, or null to use no title + * text. + * + * @param titleJustification the horizontal alignment of the title + * text in relation to the border. The value must be one of + * {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, {@link #LEADING}, + * {@link #TRAILING}, or {@link #DEFAULT_JUSTIFICATION}. + + * @param titlePosition the vertical position of the title text + * in relation to the border. The value must be one of + * {@link #ABOVE_TOP}, {@link #TOP}, {@link #BELOW_TOP}, + * {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link #BELOW_BOTTOM}, + * or {@link #DEFAULT_POSITION}. + * + * @throws IllegalArgumentException if titleJustification + * or titlePosition have an unsupported value. + */ + public TitledBorder(Border border, String title, int titleJustification, + int titlePosition) + { + this(border, title, titleJustification, titlePosition, + /* titleFont */ null, /* titleColor */ null); + } + + + /** + * Constructs a TitledBorder given its border, title text, horizontal + * alignment, vertical position, and font. + * + * @param border the border underneath the title, or null + * to use a default from the current look and feel. + * + * @param title the title text, or null to use no title + * text. + * + * @param titleJustification the horizontal alignment of the title + * text in relation to the border. The value must be one of + * {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, {@link #LEADING}, + * {@link #TRAILING}, or {@link #DEFAULT_JUSTIFICATION}. + * + * @param titlePosition the vertical position of the title text + * in relation to the border. The value must be one of + * {@link #ABOVE_TOP}, {@link #TOP}, {@link #BELOW_TOP}, + * {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link #BELOW_BOTTOM}, + * or {@link #DEFAULT_POSITION}. + * + * @param titleFont the font for the title text, or null + * to use a default from the current look and feel. + * + * @throws IllegalArgumentException if titleJustification + * or titlePosition have an unsupported value. + */ + public TitledBorder(Border border, String title, int titleJustification, + int titlePosition, Font titleFont) + { + this(border, title, titleJustification, titlePosition, titleFont, + /* titleColor */ null); + } + + + /** + * Constructs a TitledBorder given its border, title text, horizontal + * alignment, vertical position, font, and color. + * + * @param border the border underneath the title, or null + * to use a default from the current look and feel. + * + * @param title the title text, or null to use no title + * text. + * + * @param titleJustification the horizontal alignment of the title + * text in relation to the border. The value must be one of + * {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, {@link #LEADING}, + * {@link #TRAILING}, or {@link #DEFAULT_JUSTIFICATION}. + * + * @param titlePosition the vertical position of the title text + * in relation to the border. The value must be one of + * {@link #ABOVE_TOP}, {@link #TOP}, {@link #BELOW_TOP}, + * {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link #BELOW_BOTTOM}, + * or {@link #DEFAULT_POSITION}. + * + * @param titleFont the font for the title text, or null + * to use a default from the current look and feel. + * + * @param titleColor the color for the title text, or null + * to use a default from the current look and feel. + * + * @throws IllegalArgumentException if titleJustification + * or titlePosition have an unsupported value. + */ + public TitledBorder(Border border, String title, int titleJustification, + int titlePosition, Font titleFont, Color titleColor) + { + this.border = border; + this.title = title; + + /* Invoking the setter methods ensures that the newly constructed + * TitledBorder has valid property values. + */ + setTitleJustification(titleJustification); + setTitlePosition(titlePosition); + + this.titleFont = titleFont; + this.titleColor = titleColor; + } + + + /** + * Paints the border and the title text. + * + * @param c the component whose border is to be painted. + * @param g the graphics for painting. + * @param x the horizontal position for painting the border. + * @param y the vertical position for painting the border. + * @param width the width of the available area for painting the border. + * @param height the height of the available area for painting the border. + */ + public void paintBorder(Component c, Graphics g, + int x, int y, int width, int height) + { + Rectangle borderRect = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING, + width - (EDGE_SPACING * 2), + height - (EDGE_SPACING * 2)); + Point textLoc = new Point(); + + // Save color and font. + Color savedColor = g.getColor(); + Font savedFont = g.getFont(); + + // The font metrics. + Font font = getFont(c); + g.setFont(font); + FontMetrics fm = c.getFontMetrics(font); + + layoutBorderWithTitle(c, fm, borderRect, textLoc); + paintBorderWithTitle(c, g, x, y, width, height, borderRect, textLoc, fm); + + g.setColor(getTitleColor()); + g.drawString(getTitle(), textLoc.x, textLoc.y); + g.setFont(savedFont); + g.setColor(savedColor); + } + + /** + * Calculates the bounding box of the inner border and the location of the + * title string. + * + * @param c the component on which to paint the border + * @param fm the font metrics + * @param borderRect output parameter, holds the bounding box of the inner + * border on method exit + * @param textLoc output parameter, holds the location of the title text + * on method exit + */ + private void layoutBorderWithTitle(Component c, FontMetrics fm, + Rectangle borderRect, + Point textLoc) + { + Border b = getBorder(); + + // The font metrics. + int fontHeight = fm.getHeight(); + int fontDescent = fm.getDescent(); + int fontAscent = fm.getAscent(); + int titleWidth = fm.stringWidth(getTitle()); + + // The base insets. + Insets insets; + if (b == null) + insets = new Insets(0, 0, 0, 0); + else + insets = b.getBorderInsets(c); + + // The offset of the border rectangle, dependend on the title placement. + int offset; + + // Layout border and text vertically. + int titlePosition = getTitlePosition(); + switch (titlePosition) + { + case ABOVE_BOTTOM: + textLoc.y = borderRect.y + borderRect.height - insets.bottom + - fontDescent - TEXT_SPACING; + break; + case BOTTOM: + borderRect.height -= fontHeight / 2; + textLoc.y = borderRect.y + borderRect.height - fontDescent + + (fontAscent + fontDescent - insets.bottom) / 2; + break; + case BELOW_BOTTOM: + borderRect.height -= fontHeight; + textLoc.y = borderRect.y + borderRect.height + fontAscent + + TEXT_SPACING; + break; + case ABOVE_TOP: + offset = fontAscent + fontDescent + + Math.max(EDGE_SPACING, TEXT_SPACING * 2) - EDGE_SPACING; + borderRect.y += offset; + borderRect.height -= offset; + textLoc.y = borderRect.y - (fontDescent + TEXT_SPACING); + break; + case BELOW_TOP: + textLoc.y = borderRect.y + insets.top + fontAscent + TEXT_SPACING; + break; + case TOP: + case DEFAULT_POSITION: + default: + offset = Math.max(0, ((fontAscent / 2) + TEXT_SPACING) - EDGE_SPACING); + borderRect.y += offset; + borderRect.height -= offset; + textLoc.y = borderRect.y - fontDescent + + (insets.top + fontAscent + fontDescent) / 2; + break; + } + + // Layout border and text horizontally. + int justification = getTitleJustification(); + // Adjust justification for LEADING and TRAILING depending on the direction + // of the component. + if (c.getComponentOrientation().isLeftToRight()) + { + if (justification == LEADING || justification == DEFAULT_JUSTIFICATION) + justification = LEFT; + else if (justification == TRAILING) + justification = RIGHT; + } + else + { + if (justification == LEADING || justification == DEFAULT_JUSTIFICATION) + justification = RIGHT; + else if (justification == TRAILING) + justification = LEFT; + } + + switch (justification) + { + case CENTER: + textLoc.x = borderRect.x + (borderRect.width - titleWidth) / 2; + break; + case RIGHT: + textLoc.x = borderRect.x + borderRect.width - titleWidth + - TEXT_INSET_H - insets.right; + break; + case LEFT: + default: + textLoc.x = borderRect.x + TEXT_INSET_H + insets.left; + } + } + + /** + * Paints the border with the title. + * + * @param c the component to paint on + * @param g the graphics context used for paintin + * @param x the upper left corner of the whole border + * @param y the upper left corner of the whole border + * @param width the width of the whole border + * @param height the width of the whole border + * @param borderRect the bounding box of the inner border + * @param textLoc the location of the border title + * @param fm the font metrics of the title + */ + private void paintBorderWithTitle(Component c, Graphics g, int x, int y, + int width, int height, + Rectangle borderRect, Point textLoc, + FontMetrics fm) + { + Border b = getBorder(); + int fontDescent = fm.getDescent(); + int fontAscent = fm.getAscent(); + int titleWidth = fm.stringWidth(getTitle()); + + if (b != null) + { + // Paint border in segments, when the title is painted above the + // border. + if (((titlePosition == TOP || titlePosition == DEFAULT_POSITION) + && (borderRect.y > textLoc.y - fontAscent)) + || (titlePosition == BOTTOM + && borderRect.y + borderRect.height < textLoc.y + fontDescent)) + { + Rectangle clip = new Rectangle(); + Rectangle saved = g.getClipBounds(); + + // Paint border left from the text. + clip.setBounds(saved); + SwingUtilities.computeIntersection(x, y, textLoc.x - x - 1, + height, clip); + if (! clip.isEmpty()) + { + g.setClip(clip); + b.paintBorder(c, g, borderRect.x, borderRect.y, + borderRect.width, + borderRect.height); + } + // Paint border right from the text. + clip.setBounds(saved); + SwingUtilities.computeIntersection(textLoc.x + titleWidth + 1, y, + x + width - (textLoc.x + titleWidth + 1), height, clip); + if (! clip.isEmpty()) + { + g.setClip(clip); + b.paintBorder(c, g, borderRect.x, borderRect.y, + borderRect.width, + borderRect.height); + } + + if (titlePosition == TOP || titlePosition == DEFAULT_POSITION) + { + // Paint border below the text. + clip.setBounds(saved); + SwingUtilities.computeIntersection(textLoc.x - 1, + textLoc.y + fontDescent, + titleWidth + 2, + y + height - textLoc.y - fontDescent, + clip); + if (! clip.isEmpty()) + { + g.setClip(clip); + b.paintBorder(c, g, borderRect.x, borderRect.y, + borderRect.width, + borderRect.height); + } + + } + else + { + // Paint border above the text. + clip.setBounds(saved); + SwingUtilities.computeIntersection(textLoc.x - 1, y, + titleWidth + 2, + textLoc.y - fontDescent - y, + clip); + if (! clip.isEmpty()) + { + g.setClip(clip); + b.paintBorder(c, g, borderRect.x, borderRect.y, + borderRect.width, + borderRect.height); + } + + } + g.setClip(saved); + } + else + { + b.paintBorder(c, g, borderRect.x, borderRect.y, borderRect.width, + borderRect.height); + } + } + } + + /** + * Measures the width of this border. + * + * @param c the component whose border is to be measured. + * + * @return an Insets object whose left, right, + * top and bottom fields indicate the + * width of the border at the respective edge. + * + * @see #getBorderInsets(java.awt.Component, java.awt.Insets) + */ + public Insets getBorderInsets(Component c) + { + return getBorderInsets(c, new Insets(0, 0, 0, 0)); + } + + + /** + * Measures the width of this border, storing the results into a + * pre-existing Insets object. + * + * @param insets an Insets object for holding the result values. + * After invoking this method, the left, + * right, top and + * bottom fields indicate the width of the + * border at the respective edge. + * + * @return the same object that was passed for insets. + * + * @see #getBorderInsets(Component) + */ + public Insets getBorderInsets(Component c, Insets insets) + { + // Initialize insets with the insets from our border. + Border border = getBorder(); + if (border != null) + { + if (border instanceof AbstractBorder) + { + AbstractBorder aBorder = (AbstractBorder) border; + aBorder.getBorderInsets(c, insets); + } + else + { + Insets i = border.getBorderInsets(c); + insets.top = i.top; + insets.bottom = i.bottom; + insets.left = i.left; + insets.right = i.right; + } + } + else + { + insets.top = 0; + insets.bottom = 0; + insets.left = 0; + insets.right = 0; + } + + // Add spacing. + insets.top += EDGE_SPACING + TEXT_SPACING; + insets.bottom += EDGE_SPACING + TEXT_SPACING; + insets.left += EDGE_SPACING + TEXT_SPACING; + insets.right += EDGE_SPACING + TEXT_SPACING; + + String title = getTitle(); + if (c != null && title != null && !title.equals("")) + { + Font font = getFont(c); + FontMetrics fm = c.getFontMetrics(font); + int ascent = fm.getAscent(); + int descent = fm.getDescent(); + int height = fm.getHeight(); + switch (getTitlePosition()) + { + case ABOVE_BOTTOM: + insets.bottom += ascent + descent + TEXT_SPACING; + break; + case BOTTOM: + insets.bottom += ascent + descent; + break; + case BELOW_BOTTOM: + insets.bottom += height; + break; + case ABOVE_TOP: + insets.top += ascent + descent + + Math.max(EDGE_SPACING, TEXT_SPACING * 2) + - EDGE_SPACING; + break; + case BELOW_TOP: + insets.top += ascent + descent + TEXT_SPACING; + break; + case TOP: + case DEFAULT_POSITION: + default: + insets.top += ascent + descent; + } + } + return insets; + } + + + /** + * Returns false, indicating that there are pixels inside + * the area of this border where the background shines through. + * + * @return false. + */ + public boolean isBorderOpaque() + { + /* Note that the AbstractBorder.isBorderOpaque would also return + * false, so there is actually no need to override the inherited + * implementation. However, GNU Classpath strives for exact + * compatibility with the Sun reference implementation, which + * overrides isBorderOpaque for unknown reasons. + */ + return false; + } + + + /** + * Returns the text of the title. + * + * @return the title text, or null if no title is + * displayed. + */ + public String getTitle() + { + return title; + } + + + /** + * Retrieves the border underneath the title. If no border has been + * set, or if it has been set tonull, the current + * {@link javax.swing.LookAndFeel} will be asked for a border + * using the key TitledBorder.border. + * + * @return a border, or null if the current LookAndFeel + * does not provide a border for the key + * TitledBorder.border. + * + * @see javax.swing.UIManager#getBorder(Object) + */ + public Border getBorder() + { + if (border != null) + return border; + + return UIManager.getBorder("TitledBorder.border"); + } + + + /** + * Returns the vertical position of the title text in relation + * to the border. + * + * @return one of the values {@link #ABOVE_TOP}, {@link #TOP}, + * {@link #BELOW_TOP}, {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, + * {@link #BELOW_BOTTOM}, or {@link #DEFAULT_POSITION}. + */ + public int getTitlePosition() + { + return titlePosition; + } + + + /** + * Returns the horizontal alignment of the title text in relation to + * the border. + * + * @return one of the values {@link #LEFT}, {@link #CENTER}, {@link + * #RIGHT}, {@link #LEADING}, {@link #TRAILING}, or {@link + * #DEFAULT_JUSTIFICATION}. + */ + public int getTitleJustification() + { + return titleJustification; + } + + + /** + * Retrieves the font for displaying the title text. If no font has + * been set, or if it has been set tonull, the current + * {@link javax.swing.LookAndFeel} will be asked for a font + * using the key TitledBorder.font. + * + * @return a font, or null if the current LookAndFeel + * does not provide a font for the key + * TitledBorder.font. + * + * @see javax.swing.UIManager#getFont(Object) + */ + public Font getTitleFont() + { + if (titleFont != null) + return titleFont; + + return UIManager.getFont("TitledBorder.font"); + } + + + /** + * Retrieves the color for displaying the title text. If no color has + * been set, or if it has been set tonull, the current + * {@link javax.swing.LookAndFeel} will be asked for a color + * using the key TitledBorder.titleColor. + * + * @return a color, or null if the current LookAndFeel + * does not provide a color for the key + * TitledBorder.titleColor. + * + * @see javax.swing.UIManager#getColor(Object) + */ + public Color getTitleColor() + { + if (titleColor != null) + return titleColor; + + return UIManager.getColor("TitledBorder.titleColor"); + } + + + /** + * Sets the text of the title. + * + * @param title the new title text, or null for displaying + * no text at all. + */ + public void setTitle(String title) + { + // Swing borders are not JavaBeans, thus no need to fire an event. + this.title = title; + } + + + /** + * Sets the border underneath the title. + * + * @param border a border, or null to use the + * border that is supplied by the current LookAndFeel. + * + * @see #getBorder() + */ + public void setBorder(Border border) + { + // Swing borders are not JavaBeans, thus no need to fire an event. + this.border = border; + } + + + /** + * Sets the vertical position of the title text in relation + * to the border. + * + * @param titlePosition one of the values {@link #ABOVE_TOP}, + * {@link #TOP}, {@link #BELOW_TOP}, {@link #ABOVE_BOTTOM}, + * {@link #BOTTOM}, {@link #BELOW_BOTTOM}, + * or {@link #DEFAULT_POSITION}. + * + * @throws IllegalArgumentException if an unsupported value is passed + * for titlePosition. + */ + public void setTitlePosition(int titlePosition) + { + if ((titlePosition < DEFAULT_POSITION) || (titlePosition > BELOW_BOTTOM)) + throw new IllegalArgumentException(titlePosition + + " is not a valid title position."); + + // Swing borders are not JavaBeans, thus no need to fire an event. + this.titlePosition = titlePosition; + } + + + /** + * Sets the horizontal alignment of the title text in relation to the border. + * + * @param titleJustification the new alignment, which must be one of + * {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, {@link #LEADING}, + * {@link #TRAILING}, or {@link #DEFAULT_JUSTIFICATION}. + * + * @throws IllegalArgumentException if an unsupported value is passed + * for titleJustification. + */ + public void setTitleJustification(int titleJustification) + { + if ((titleJustification < DEFAULT_JUSTIFICATION) + || (titleJustification > TRAILING)) + throw new IllegalArgumentException(titleJustification + + " is not a valid title justification."); + + // Swing borders are not JavaBeans, thus no need to fire an event. + this.titleJustification = titleJustification; + } + + + /** + * Sets the font for displaying the title text. + * + * @param titleFont the font, or null to use the font + * provided by the current {@link javax.swing.LookAndFeel}. + * + * @see #getTitleFont() + */ + public void setTitleFont(Font titleFont) + { + // Swing borders are not JavaBeans, thus no need to fire an event. + this.titleFont = titleFont; + } + + + /** + * Sets the color for displaying the title text. + * + * @param titleColor the color, or null to use the color + * provided by the current {@link javax.swing.LookAndFeel}. + * + * @see #getTitleColor() + */ + public void setTitleColor(Color titleColor) + { + // Swing borders are not JavaBeans, thus no need to fire an event. + this.titleColor = titleColor; + } + + + /** + * Calculates the minimum size needed for displaying the border + * and its title. + * + * @param c the Component for which this TitledBorder constitutes + * a border. + * + * @return The minimum size. + */ + public Dimension getMinimumSize(Component c) + { + Insets i = getBorderInsets(c); + Dimension minSize = new Dimension(i.left + i.right, i.top + i.bottom); + Font font = getFont(c); + FontMetrics fm = c.getFontMetrics(font); + int titleWidth = fm.stringWidth(getTitle()); + switch (getTitlePosition()) + { + case ABOVE_TOP: + case BELOW_BOTTOM: + minSize.width = Math.max(minSize.width, titleWidth); + break; + case BELOW_TOP: + case ABOVE_BOTTOM: + case TOP: + case BOTTOM: + case DEFAULT_POSITION: + default: + minSize.width += titleWidth; + } + return minSize; + } + + + /** + * Returns the font that is used for displaying the title text for + * a given Component. + * + * @param c the Component for which this TitledBorder is the border. + * + * @return The font returned by {@link #getTitleFont()}, or a fallback + * if {@link #getTitleFont()} returned null. + */ + protected Font getFont(Component c) + { + Font f; + + f = getTitleFont(); + if (f != null) + return f; + + return new Font("Dialog", Font.PLAIN, 12); + } + +} diff --git a/libjava/classpath/javax/swing/border/doc-files/BevelBorder-1.png b/libjava/classpath/javax/swing/border/doc-files/BevelBorder-1.png new file mode 100644 index 000000000..8c3e4b277 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/BevelBorder-1.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/BevelBorder-2.png b/libjava/classpath/javax/swing/border/doc-files/BevelBorder-2.png new file mode 100644 index 000000000..ac52d47a7 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/BevelBorder-2.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/BevelBorder-3.png b/libjava/classpath/javax/swing/border/doc-files/BevelBorder-3.png new file mode 100644 index 000000000..dd531ff68 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/BevelBorder-3.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/EmptyBorder-1.png b/libjava/classpath/javax/swing/border/doc-files/EmptyBorder-1.png new file mode 100644 index 000000000..2f21140b1 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/EmptyBorder-1.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/EtchedBorder-1.png b/libjava/classpath/javax/swing/border/doc-files/EtchedBorder-1.png new file mode 100644 index 000000000..6b1085c1b Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/EtchedBorder-1.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/EtchedBorder-2.png b/libjava/classpath/javax/swing/border/doc-files/EtchedBorder-2.png new file mode 100644 index 000000000..36b07056c Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/EtchedBorder-2.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/LineBorder-1.png b/libjava/classpath/javax/swing/border/doc-files/LineBorder-1.png new file mode 100644 index 000000000..45b8afc61 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/LineBorder-1.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/MatteBorder-1.png b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-1.png new file mode 100644 index 000000000..fc49f4b43 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-1.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/MatteBorder-2.png b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-2.png new file mode 100644 index 000000000..9c2c8d955 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-2.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/MatteBorder-3.png b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-3.png new file mode 100644 index 000000000..62089eab5 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-3.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/MatteBorder-4.png b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-4.png new file mode 100644 index 000000000..bffbcc84e Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-4.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/MatteBorder-5.png b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-5.png new file mode 100644 index 000000000..807eee8df Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-5.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/MatteBorder-6.png b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-6.png new file mode 100644 index 000000000..2c4ce1e3d Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/MatteBorder-6.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-1.png b/libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-1.png new file mode 100644 index 000000000..4404bf98c Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-1.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-2.png b/libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-2.png new file mode 100644 index 000000000..ebd9849e6 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-2.png differ diff --git a/libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-3.png b/libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-3.png new file mode 100644 index 000000000..9f939b7a9 Binary files /dev/null and b/libjava/classpath/javax/swing/border/doc-files/SoftBevelBorder-3.png differ diff --git a/libjava/classpath/javax/swing/border/package.html b/libjava/classpath/javax/swing/border/package.html new file mode 100644 index 000000000..de8479a6a --- /dev/null +++ b/libjava/classpath/javax/swing/border/package.html @@ -0,0 +1,47 @@ + + + + +GNU Classpath - javax.swing.border + + +

Provides borders for use by components in the javax.swing +package.

+ + + -- cgit v1.2.3