Font.java [...]: New versions from classpath.

2003-06-19  Michael Koch  <konqueror@gmx.de>

	* java/awt/Font.java
	javax/swing/UIManager.java
	javax/swing/border/AbstractBorder.java
	javax/swing/border/BevelBorder.java
	javax/swing/border/Border.java
	javax/swing/border/CompoundBorder.java
	javax/swing/border/EmptyBorder.java
	javax/swing/border/EtchedBorder.java
	javax/swing/border/LineBorder.java
	javax/swing/border/MatteBorder.java
	javax/swing/border/TitledBorder.java
	javax/swing/plaf/BorderUIResource.java
	javax/swing/plaf/basic/BasicBorders.java
	javax/swing/plaf/basic/BasicButtonUI.java
	javax/swing/plaf/basic/BasicCheckBoxUI.java
	javax/swing/plaf/basic/BasicGraphicsUtils.java
	javax/swing/plaf/basic/BasicLabelUI.java
	javax/swing/plaf/basic/BasicRadioButtonUI.java
	javax/swing/plaf/basic/BasicToggleButtonUI.java:
	New versions from classpath.
	* javax/swing/border/SoftBevelBorder.java:
	New file from classpath.
	* javax/swing/border/doc-files/LineBorder-1.png,
	javax/swing/border/doc-files/BevelBorder-1.png,
	javax/swing/border/doc-files/BevelBorder-2.png,
	javax/swing/border/doc-files/BevelBorder-3.png,
	javax/swing/border/doc-files/EmptyBorder-1.png,
	javax/swing/border/doc-files/EtchedBorder-1.png,
	javax/swing/border/doc-files/EtchedBorder-2.png,
	javax/swing/border/doc-files/MatteBorder-1.png,
	javax/swing/border/doc-files/MatteBorder-2.png,
	javax/swing/border/doc-files/MatteBorder-3.png,
	javax/swing/border/doc-files/MatteBorder-4.png,
	javax/swing/border/doc-files/MatteBorder-5.png,
	javax/swing/border/doc-files/MatteBorder-6.png,
	javax/swing/border/doc-files/SoftBevelBorder-1.png,
	javax/swing/border/doc-files/SoftBevelBorder-2.png,
	javax/swing/border/doc-files/SoftBevelBorder-3.png,
	javax/swing/plaf/basic/doc-files/BasicBorders.MarginBorder-1.png,
	javax/swing/plaf/basic/doc-files/BasicBorders.ButtonBorder-1.png,
	javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-1.png,
	javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-2.png,
	javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-3.png,
	javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-4.png,
	javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-5.png,
	javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-6.png,
	javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-7.png:
	New binary files from classpath.
	* Makefile.am
	(awt_java_source_files): Added
	javax/swing/border/SoftBevelBorder.java.
	* Makefile.in: Regenerated.

From-SVN: r68190
This commit is contained in:
Michael Koch 2003-06-19 10:48:46 +00:00 committed by Michael Koch
parent 1681bed6c8
commit 8993c12bee
48 changed files with 4998 additions and 522 deletions

View file

@ -1,3 +1,58 @@
2003-06-19 Michael Koch <konqueror@gmx.de>
* java/awt/Font.java
javax/swing/UIManager.java
javax/swing/border/AbstractBorder.java
javax/swing/border/BevelBorder.java
javax/swing/border/Border.java
javax/swing/border/CompoundBorder.java
javax/swing/border/EmptyBorder.java
javax/swing/border/EtchedBorder.java
javax/swing/border/LineBorder.java
javax/swing/border/MatteBorder.java
javax/swing/border/TitledBorder.java
javax/swing/plaf/BorderUIResource.java
javax/swing/plaf/basic/BasicBorders.java
javax/swing/plaf/basic/BasicButtonUI.java
javax/swing/plaf/basic/BasicCheckBoxUI.java
javax/swing/plaf/basic/BasicGraphicsUtils.java
javax/swing/plaf/basic/BasicLabelUI.java
javax/swing/plaf/basic/BasicRadioButtonUI.java
javax/swing/plaf/basic/BasicToggleButtonUI.java:
New versions from classpath.
* javax/swing/border/SoftBevelBorder.java:
New file from classpath.
* javax/swing/border/doc-files/LineBorder-1.png,
javax/swing/border/doc-files/BevelBorder-1.png,
javax/swing/border/doc-files/BevelBorder-2.png,
javax/swing/border/doc-files/BevelBorder-3.png,
javax/swing/border/doc-files/EmptyBorder-1.png,
javax/swing/border/doc-files/EtchedBorder-1.png,
javax/swing/border/doc-files/EtchedBorder-2.png,
javax/swing/border/doc-files/MatteBorder-1.png,
javax/swing/border/doc-files/MatteBorder-2.png,
javax/swing/border/doc-files/MatteBorder-3.png,
javax/swing/border/doc-files/MatteBorder-4.png,
javax/swing/border/doc-files/MatteBorder-5.png,
javax/swing/border/doc-files/MatteBorder-6.png,
javax/swing/border/doc-files/SoftBevelBorder-1.png,
javax/swing/border/doc-files/SoftBevelBorder-2.png,
javax/swing/border/doc-files/SoftBevelBorder-3.png,
javax/swing/plaf/basic/doc-files/BasicBorders.MarginBorder-1.png,
javax/swing/plaf/basic/doc-files/BasicBorders.ButtonBorder-1.png,
javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-1.png,
javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-2.png,
javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-3.png,
javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-4.png,
javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-5.png,
javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-6.png,
javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-7.png:
New binary files from classpath.
* Makefile.am
(awt_java_source_files): Added
javax/swing/border/SoftBevelBorder.java.
* Makefile.in: Regenerated.
2003-06-19 Michael Koch <konqueror@gmx.de>
* gnu/java/security/x509/X509Certificate.java

View file

@ -1151,6 +1151,7 @@ javax/swing/border/EmptyBorder.java \
javax/swing/border/EtchedBorder.java \
javax/swing/border/LineBorder.java \
javax/swing/border/MatteBorder.java \
javax/swing/border/SoftBevelBorder.java \
javax/swing/border/TitledBorder.java \
javax/swing/GrayFilter.java \
javax/swing/AbstractAction.java \

View file

@ -920,6 +920,7 @@ javax/swing/border/EmptyBorder.java \
javax/swing/border/EtchedBorder.java \
javax/swing/border/LineBorder.java \
javax/swing/border/MatteBorder.java \
javax/swing/border/SoftBevelBorder.java \
javax/swing/border/TitledBorder.java \
javax/swing/GrayFilter.java \
javax/swing/AbstractAction.java \
@ -4016,6 +4017,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/javax/swing/border/EtchedBorder.P \
.deps/javax/swing/border/LineBorder.P \
.deps/javax/swing/border/MatteBorder.P \
.deps/javax/swing/border/SoftBevelBorder.P \
.deps/javax/swing/border/TitledBorder.P \
.deps/javax/swing/colorchooser/AbstractColorChooserPanel.P \
.deps/javax/swing/colorchooser/ColorChooserComponentFactory.P \

View file

@ -39,6 +39,8 @@ exception statement from your version. */
package java.awt;
import java.awt.peer.FontPeer;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.io.Serializable;
import java.util.StringTokenizer;
@ -484,5 +486,28 @@ toString()
",size=" + size + ")");
}
/**
* Determines the line metrics for a run of text.
*
* @param str the text run to be measured.
*
* @param frc the font rendering parameters that are used for the
* measurement. The exact placement and size of text slightly
* depends on device-specific characteristics, for instance
* the device resolution or anti-aliasing. For this reason,
* the returned measurement will only be accurate if the
* passed <code>FontRenderContext</code> correctly reflects
* the relevant parameters. Hence, <code>frc</code> should be
* obtained from the same <code>Graphics2D</code> that will
* be used for drawing, and any rendering hints should be set
* to the desired values before obtaining <code>frc</code>.
*
* @see java.awt.Graphics2D#getFontRenderContext()
*/
public LineMetrics getLineMetrics(String str, FontRenderContext frc)
{
throw new UnsupportedOperationException(); // FIXME
}
} // class Font

View file

@ -174,11 +174,21 @@ public class UIManager implements Serializable
System.out.println("UIManager.getDim");
return new Dimension(200,100);
}
static Font getFont(Object key)
// Returns a drawing font from the defaults table.
{
return (Font) getLookAndFeel().getDefaults().get(key);
}
/**
* Retrieves a font from the defaults table of the current
* LookAndFeel.
*
* @param key an Object that specifies the font. Typically,
* this is a String such as
* <code>&quot;TitledBorder.font&quot;</code>.
*/
public static Font getFont(Object key)
{
return (Font) getLookAndFeel().getDefaults().get(key);
}
static Icon getIcon(Object key)
// Returns an Icon from the defaults table.
{
@ -207,11 +217,17 @@ public class UIManager implements Serializable
return look_and_feel;
}
static UIDefaults getLookAndFeelDefaults()
// Returns the default values for this look and feel.
{
return getLookAndFeel().getDefaults();
}
/**
* Returns the <code>UIDefaults</code> table of the currently active
* look and feel.
*/
public static UIDefaults getLookAndFeelDefaults()
{
return getLookAndFeel().getDefaults();
}
static String getString(Object key)
// Returns a string from the defaults table.
{

View file

@ -91,15 +91,16 @@ public abstract class AbstractBorder
/**
* Determines the insets of this border. The implementation provided
* by AbstractButton returns Insets for a zero-width border, whose
* <code>left</code>, <code>right</code>, <code>top</code> and
* <code>bottom</code> fields are all zero.
* Measures the width of this border.
*
* @param c the component whose border is to be measured.
*
* @return a newly created Insets object, indicating a zero-width
* border.
* @return an Insets object whose <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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)
{
@ -113,12 +114,11 @@ public abstract class AbstractBorder
* <code>top</code> and <code>bottom</code> fields of the passed
* <code>insets</code> parameter to zero.
*
* @param c the component in the center of this border.
* @param c the component whose border is to be measured.
*
* @param insets an Insets object for holding the insets of this
* border.
* @return the same object that was passed for <code>insets</code>.
*
* @return the <code>insets</code> object.
* @see #getBorderInsets()
*/
public Insets getBorderInsets (Component c, Insets insets)
{

View file

@ -1,5 +1,5 @@
/* BevelBorder.java --
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -40,51 +40,529 @@ package javax.swing.border;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
public class BevelBorder extends AbstractBorder
/**
* 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.
*
* <p>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
{
public static final int LOWERED = 1;
/**
* Determined using the <code>serialver</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> to indicate that the
* color shall be derived from the background of the component whose
* border is being painted.
*/
protected Color shadowInner;
public BevelBorder (int bevelType)
/**
* 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&#x2019;s background color.
*
* <p><img src="BevelBorder-1.png" width="500" height="150"
* alt="[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 <code>bevelType</code> has
* an unsupported value.
*/
public BevelBorder(int bevelType)
{
this (bevelType, null, null, null, null);
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.
*
* <p><img src="BevelBorder-2.png" width="500" height="150"
* alt="[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 <code>bevelType</code> 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 <code>bevelType</code> is {@link #RAISED}; top
* and left otherwise). The color for the inner side
* is a brightened version of this color.
*
* @throws IllegalArgumentException if <code>bevelType</code> has
* an unsupported value.
*
* @throws NullPointerException if <code>highlight</code> or
* <code>shadow</code> is <code>null</code>.
*
* @see java.awt.Color.brighter()
*/
public BevelBorder(int bevelType, Color highlight, Color shadow)
{
this (bevelType, highlight, highlight, shadow, shadow);
this(bevelType,
/* highlightOuter */ highlight.brighter(),
/* highlightInner */ highlight,
/* shadowOuter */ shadow,
/* shadowInner */ shadow.brighter());
}
public BevelBorder (int bevelType, Color highlightOuter,
Color highlightInner, Color shadowOuter,
Color shadowInner)
/**
* Constructs a BevelBorder given its appearance type and all
* colors.
*
* <p><img src="BevelBorder-3.png" width="500" height="150"
* alt="[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
* <code>bevelType</code> 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 <code>bevelType</code> 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 <code>bevelType</code> has
* an unsupported value.
*
* @throws NullPointerException if one of the passed colors
* is <code>null</code>.
*/
public BevelBorder(int bevelType,
Color highlightOuter, Color highlightInner,
Color shadowOuter, Color shadowInner)
{
this.bevelType = bevelType;
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;
}
public boolean isBorderOpaque()
/**
* 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)
{
return false;
case RAISED:
paintRaisedBevel(c, g, x, y, width, height);
break;
case LOWERED:
paintLoweredBevel(c, g, x, y, width, height);
break;
}
public 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 <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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 <code>left</code>,
* <code>right</code>, <code>top</code> and
* <code>bottom</code> fields indicate the width of the
* border at the respective edge.
*
* @return the same object that was passed for <code>insets</code>.
*
* @see #getBorderInsets()
*/
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.
*
* @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.
*
* @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.
*
* @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.
*
* @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 <code>null</code>
* if that color will be derived from the background of the enclosed
* Component.
*/
public Color getHighlightOuterColor()
{
return highlightOuter;
}
/**
* Returns the color that will be used for the inner side of
* highlighted edges when painting the border, or <code>null</code>
* if that color will be derived from the background of the enclosed
* Component.
*/
public Color getHighlightInnerColor()
{
return highlightInner;
}
/**
* Returns the color that will be used for the inner side of
* shadowed edges when painting the border, or <code>null</code> if
* that color will be derived from the background of the enclosed
* Component.
*/
public Color getShadowInnerColor()
{
return shadowInner;
}
/**
* Returns the color that will be used for the outer side of
* shadowed edges when painting the border, or <code>null</code> if
* that color will be derived from the background of the enclosed
* Component.
*/
public Color getShadowOuterColor()
{
return shadowOuter;
}
/**
* Returns the appearance of this border, which is either {@link
* #RAISED} or {@link #LOWERED}.
*/
public int getBevelType()
{
return bevelType;
}
/**
* Determines whether this border fills every pixel in its area
* when painting.
*
* <p>If the border colors are derived from the background color of
* the enclosed component, the result is <code>true</code> because
* the derivation method always returns opaque colors. Otherwise,
* the result depends on the opacity of the individual colors.
*
* @return <code>true</code> if the border is fully opaque, or
* <code>false</code> 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.
*
* <pre>
* @@@@@@@@@@@@
* @..........# @ = color a
* @. X# . = color b
* @. X# X = color c
* @.XXXXXXXXX# # = color d
* ############</pre>
*
* @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);
}
}
}

View file

@ -1,5 +1,5 @@
/* Border.java --
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -42,10 +42,64 @@ import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
/**
* An interface for decorative or spacing borders around a Component.
*
* <p>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
{
public Insets getBorderInsets (Component c);
public boolean isBorderOpaque ();
public void paintBorder (Component c, Graphics g, int x, int y,
int width, int height);
/**
* 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);
/**
* Measures the width of this border.
*
* @param c the component whose border is to be measured.
*
* @return an Insets object whose <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> fields indicate the
* width of the border at the respective edge.
*/
public Insets getBorderInsets(Component c);
/**
* Determines whether this border fills every pixel in its area
* when painting.
*
* @return <code>true</code> if the border is fully opaque, or
* <code>false</code> if some pixels of the background
* can shine through the border.
*/
public boolean isBorderOpaque();
}

View file

@ -51,6 +51,10 @@ import java.awt.Insets;
public class CompoundBorder
extends AbstractBorder
{
/**
* Determined using the <code>serialver</code> tool
* of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
*/
static final long serialVersionUID = 9054540377030555103L;
@ -90,14 +94,14 @@ public class CompoundBorder
* outside borders.
*
* @param outsideBorder the outside border, which is painted to the
* outside of both <code>insideBorder</code> and the bordered
* compoonent. It is acceptable to pass <code>null</code>, in
* which no outside border is painted.
* outside of both <code>insideBorder</code> and the enclosed
* component. It is acceptable to pass <code>null</code>, in
* which case no outside border is painted.
*
* @param insideBorder the inside border, which is painted to
* between <code>outsideBorder</code> and the bordered
* between <code>outsideBorder</code> and the enclosed
* component. It is acceptable to pass <code>null</code>, in
* which no intside border is painted.
* which case no inside border is painted.
*/
public CompoundBorder (Border outsideBorder, Border insideBorder)
{

View file

@ -1,5 +1,5 @@
/* EmptyBorder.java --
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -42,47 +42,182 @@ import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
public class EmptyBorder extends AbstractBorder
/**
* 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.
*
* <p><img src="EmptyBorder-1.png" width="290" height="200"
* alt="[An illustration of EmptyBorder]" />
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class EmptyBorder
extends AbstractBorder
{
/**
* Determined using the <code>serialver</code> 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;
protected int bottom;
/**
* The number of pixels required at the top edge.
*/
protected int top;
public EmptyBorder (Insets borderInsets)
{
this (borderInsets.left, borderInsets.right,
borderInsets.top, borderInsets.bottom);
}
public EmptyBorder (int left, int right, int top, int bottom)
/**
* 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.left = left;
this.right = right;
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
public Insets getBorderInsets (Component c, Insets s)
{
if (s == null)
s = new Insets (0,0,0,0);
s.left = left;
s.right = right;
s.top = top;
s.bottom = bottom;
return s;
}
public boolean isBorderOpaque ()
/**
* 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)
{
}
/**
* Measures the width of this border.
*
* @param c the component whose border is to be measured.
*
* @return an Insets object whose <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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 <code>left</code>,
* <code>right</code>, <code>top</code> and
* <code>bottom</code> fields indicate the width of the
* border at the respective edge.
*
* @return the same object that was passed for <code>insets</code>.
*
* @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 <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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 <code>false</code>.
*
* @return <code>false</code>.
*/
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;
}
public void paintBorder (Component c, Graphics g, int x, int y,
int width, int height)
{
}
}

View file

@ -1,5 +1,5 @@
/* EtchedBorder.java --
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -41,50 +41,371 @@ package javax.swing.border;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
public class EtchedBorder extends AbstractBorder
/**
* 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.
*
* <p><img src="EtchedBorder-1.png" width="500" height="200"
* alt="[An illustration of the two EtchedBorder variants]" />
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class EtchedBorder
extends AbstractBorder
{
public static final int LOWERED = 1;
/**
* Determined using the <code>serialver</code> 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 <code>null</code> to indicate that the
* color shall be derived from the background of the enclosed
* component.
*/
protected Color highlight;
/**
* The shadow color, or <code>null</code> to indicate that the
* color shall be derived from the background of the enclosed
* component.
*/
protected Color shadow;
public EtchedBorder ()
/**
* 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, null, null);
this(LOWERED);
}
public EtchedBorder (Color highlight, Color shadow)
{
this (LOWERED, highlight, shadow);
}
public EtchedBorder (int etchType)
/**
* 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.
*
* <p><img src="EtchedBorder-1.png" width="500" height="200"
* alt="[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 <code>etchType</code> has
* an unsupported value.
*/
public EtchedBorder(int etchType)
{
this (etchType, null, null);
}
if ((etchType != RAISED) && (etchType != LOWERED))
throw new IllegalArgumentException();
public EtchedBorder (int etchType, Color highlight, Color shadow)
{
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.
*
* <p><img src="EtchedBorder-2.png" width="500" height="200"
* alt="[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 <code>etchType</code> 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;
}
public boolean isBorderOpaque()
/**
* 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)
{
return false;
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;
}
public 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 <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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 <code>left</code>,
* <code>right</code>, <code>top</code> and
* <code>bottom</code> fields indicate the width of the
* border at the respective edge.
*
* @return the same object that was passed for <code>insets</code>.
*
* @see #getBorderInsets()
*/
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.
*
* <p>If the border colors are derived from the background color of
* the enclosed component, the result is <code>true</code> because
* the derivation method always returns opaque colors. Otherwise,
* the result depends on the opacity of the individual colors.
*
* @return <code>true</code> if the border is fully opaque, or
* <code>false</code> 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
((highlight == null) || (highlight.getAlpha() == 255))
&& ((shadow == null) || (shadow.getAlpha() == 255));
}
/**
* Returns the appearance of this EtchedBorder, which is either
* {@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.
*
* @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 <code>null</code> if that color will be
* derived from the background of the enclosed Component.
*/
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.
*
* @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 <code>null</code> if that color will be
* derived from the background of the enclosed Component.
*/
public Color getShadowColor()
{
return shadow;
}
/**
* Paints a two-pixel etching in two colors.
*
* <pre>
* @@@@@@@@@@@.
* @.........@. @ = color a
* @. @. . = color b
* @. @.
* @@@@@@@@@@@.
* ............</pre>
*
* @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);
}
}
}

View file

@ -1,5 +1,5 @@
/* LineBorder.java --
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -41,45 +41,294 @@ package javax.swing.border;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
public class LineBorder extends AbstractBorder
/**
* 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
{
protected Color lineColor;
protected boolean roundedCorners;
protected int thickness;
/**
* Determined using the <code>serialver</code> tool
* of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
*/
static final long serialVersionUID = -787563427772288970L;
public LineBorder (Color color)
{
this (color, 1);
}
public LineBorder (Color color, int thickness)
{
this (color, thickness, false); // FIXME: check roundedCorners argument
}
/**
* 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
* #createBlackGrayBorder()} 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
* (<code>true</code>) or not ((<code>false</code>).
*/
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.
*
* <p><img src="LineBorder-1.png" width="500" height="200"
* alt="[An illustration of two LineBorders] />
*
* <p>Note that the enlarged view in the right-hand picture shows
* that the implementation draws one more pixel than specified,
* provided that <code>roundedCorders</code> is <code>true</code>
* 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 <code>true</code> for rounded corners,
* <code>false</code> for plain corners.
*
* @since 1.3
*/
public LineBorder (Color color, int thickness, boolean roundedCorners)
// 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 LineBorder. The method
* may always return the same (singleton) LineBorder instance.
*/
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);
public boolean isBorderOpaque()
{
return false;
}
return blackLineBorder;
}
/**
* Returns a gray, one pixel thick, plain LineBorder. The method
* may always return the same (singleton) LineBorder instance.
*/
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);
public void paintBorder(Component c,
Graphics g,
int x,
int y,
int width,
int height)
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 <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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 <code>left</code>,
* <code>right</code>, <code>top</code> and
* <code>bottom</code> 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 <code>insets</code>.
*
* @see #getBorderInsets()
*/
public Insets getBorderInsets(Component c, Insets insets)
{
insets.left = insets.right = insets.top = insets.bottom = thickness;
return insets;
}
/**
* Returns the thickness of the line in pixels.
*/
public int getThickness()
{
return thickness;
}
/**
* Returns whether this LineBorder os drawm with rounded
* or with plain corners.
*
* @return <code>true</code> if the corners are rounded,
* <code>false</code> if the corners are plain.
*/
public boolean getRoundedCorners()
{
return roundedCorners;
}
/**
* Determines whether this border fills every pixel in its area
* when painting.
*
* @return <code>true</code> if the corners are plain and the line
* color is fully opaque; <code>false</code> if the corners
* are rounded or the line color is partially transparent.
*/
public boolean isBorderOpaque()
{
return (!roundedCorners) && (lineColor.getAlpha() == 255);
}
}

View file

@ -1,5 +1,5 @@
/* MatteBorder.java --
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -44,53 +44,361 @@ import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.Icon;
public class MatteBorder extends EmptyBorder
/**
* A border that is filled with either a solid color or with repeated
* icon tiles.
*
* <p><img src="MatteBorder-1.png" width="500" height="150"
* alt="[Two MatteBorders]" />
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class MatteBorder
extends EmptyBorder
{
/**
* Determined using the <code>serialver</code> 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
* <code>null</code> 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
* <code>null</code> if the border is filled with a solid
* color.
*
* @see #color
*/
protected Icon tileIcon;
public MatteBorder (Icon tileIcon)
/**
* Constructs a MatteBorder given the width on each side
* and a fill color.
*
* <p><img src="MatteBorder-2.png" width="500" height="150"
* alt="[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)
{
// FIXME: implement this
this (null, tileIcon);
super(top, left, bottom, right);
if (matteColor == null)
throw new IllegalArgumentException();
this.color = matteColor;
}
public MatteBorder (Insets borderInsets, Color color)
/**
* Constructs a MatteBorder given its insets and fill color.
*
* <p><img src="MatteBorder-3.png" width="500" height="150"
* alt="[A picture of a MatteBorder made by this constructor]" />
*
* @param borderInsets an Insets object whose <code>top</code>,
* <code>left</code>, <code>bottom</code> and <code>right</code>
* 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, color);
this(borderInsets.top, borderInsets.left,
borderInsets.bottom, borderInsets.right,
matteColor);
}
public MatteBorder (Insets borderInsets, Icon tileIcon)
{
this (borderInsets.top, borderInsets.left, borderInsets.bottom,
borderInsets.right, tileIcon);
}
public MatteBorder (int top, int left, int bottom, int right, Icon tileIcon)
/**
* Constructs a MatteBorder given the width on each side
* and an icon for tiling the border area.
*
* <p><img src="MatteBorder-4.png" width="500" height="150"
* alt="[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);
super(top, left, bottom, right);
if (tileIcon == null)
throw new IllegalArgumentException();
this.tileIcon = tileIcon;
}
public MatteBorder (int top, int left, int bottom, int right, Color color)
/**
* Constructs a MatteBorder given its insets and an icon
* for tiling the border area.
*
* <p><img src="MatteBorder-5.png" width="500" height="150"
* alt="[A picture of a MatteBorder made by this constructor]" />
*
* @param borderInsets an Insets object whose <code>top</code>,
* <code>left</code>, <code>bottom</code> and <code>right</code>
* 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)
{
super (top, left, bottom, right);
this.color = color;
this(borderInsets.top, borderInsets.left,
borderInsets.bottom, borderInsets.right,
tileIcon);
}
public boolean isBorderOpaque()
/**
* 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.
*
* <p><img src="MatteBorder-6.png" width="500" height="150"
* alt="[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 <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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 <code>left</code>,
* <code>right</code>, <code>top</code> and
* <code>bottom</code> fields indicate the width of the
* border at the respective edge.
*
* @return the same object that was passed for <code>insets</code>.
*
* @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))
{
return false;
insets.left = insets.right = tileIcon.getIconWidth();
insets.top = insets.bottom = tileIcon.getIconHeight();
return insets;
}
public void paintBorder(Component c,
Graphics g,
int x,
int y,
int width,
int height)
/* 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 <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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
* <code>null</code> if the border is filled with repetitions of a
* tile icon.
*/
public Color getMatteColor()
{
return color;
}
/**
* Returns the icon is used for tiling the border, or
* <code>null</code> if the border is filled with a color instead of
* an icon.
*/
public Icon getTileIcon()
{
return tileIcon;
}
/**
* Determines whether this border fills every pixel in its area
* when painting.
*
* @return <code>true</code> if the border is filled with an
* opaque color; <code>false</code> 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;
}
/* 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();
}
}
}

View file

@ -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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.
*
* <p>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 <code>serialver</code> tool
* of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
*/
static final long serialVersionUID = -6658357140774549493L;
/**
* 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&#x2019;s background color.
*
* <p><img src="SoftBevelBorder-1.png" width="500" height="200"
* alt="[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 <code>bevelType</code> 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.
*
* <p><img src="SoftBevelBorder-2.png" width="500" height="150"
* alt="[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
* <code>bevelType</code> 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
* <code>bevelType</code> is {@link BevelBorder#RAISED}; top
* and left otherwise). The color for the inner side is a
* brightened version of this color.
*
* @throws IllegalArgumentException if <code>bevelType</code> has an
* unsupported value.
*
* @throws NullPointerException if <code>highlight</code> or
* <code>shadow</code> is <code>null</code>.
*
* @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.
*
* <p><img src="SoftBevelBorder-3.png" width="500" height="150"
* alt="[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
* <code>bevelType</code> 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
* <code>bevelType</code> 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 <code>bevelType</code> has
* an unsupported value.
*
* @throws NullPointerException if one of the passed colors
* is <code>null</code>.
*/
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 <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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 <code>left</code>,
* <code>right</code>, <code>top</code> and
* <code>bottom</code> fields indicate the width of the
* border at the respective edge.
*
* @return the same object that was passed for <code>insets</code>.
*
* @see #getBorderInsets()
*/
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.
*
* <p>The enlarged view (see documentation for constructors) shows
* that a SoftBevelBorder does not paint all pixels. Therefore,
* this method always returns <code>false</code>.
*
* @return <code>false</code>.
*/
public boolean isBorderOpaque()
{
return false;
}
/**
* Paints a soft bevel in four colors.
*
* <pre>
* @@@@@@@@@@@.
* @@.........# @ = color a
* @.. # . = color b
* @. # X = color c
* .. X# # = color d
* . ##########</pre>
*
* @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);
}
}
}

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/* BasicBorders.java
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -37,15 +37,281 @@ exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
import java.io.Serializable;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JPopupMenu;
import javax.swing.JToolBar;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.BorderUIResource;
/**
* STUBBED
* Provides various borders for the Basic look and feel.
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class BasicBorders
{
public static class ButtonBorder
/**
* A MarginBorder that gets shared by multiple components.
* Created on demand by the private helper function {@link
* #getMarginBorder()}.
*/
private static MarginBorder sharedMarginBorder;
/**
* Returns a border that is suitable for a button.
*
* <p>The colors of the border are retrieved from the
* <code>UIDefaults</code> of the currently active look and feel
* using the keys <code>&#x201c;Button.shadow&#x201d;</code>,
* <code>&#x201c;Button.darkShadow&#x201d;</code>,
* <code>&#x201c;Button.light&#x201d;</code>, and
* <code>&#x201c;Button.highlight&#x201d;</code>.
*
* <p><img src="BasicBorders.ButtonBorder-1.png" width="300"
* height="170" alt="[A screen shot of the returned border]" />
*
* @return a {@link
* javax.swing.plaf.BorderUIResource#CompoundBorderUIResource}
* whose outer border is a {@link #ButtonBorder} and whose
* inner border is a {@link #MarginBorder}.
*/
public static Border getButtonBorder()
{
} // class ButtonBorder
UIDefaults defaults;
Border outer;
defaults = UIManager.getLookAndFeelDefaults();
/* The keys for UIDefaults have been determined by writing a
* test program that dumps the UIDefaults to stdout; that program
* was run on a JDK 1.4.1_01 for GNU/Linux. Note that in the API,
* the key "light" is usually called "highlight", and "highlight"
* is usually called "lightHighlight".
*/
outer = new ButtonBorder(defaults.getColor("Button.shadow"),
defaults.getColor("Button.darkShadow"),
defaults.getColor("Button.light"),
defaults.getColor("Button.highlight"));
/* While the inner border is shared between multiple buttons,
* we do not share the outer border because ButtonBorders store
* their border colors. We cannot guarantee that the colors
* (which come from UIDefaults) are unchanged between invocations
* of getButtonBorder. We could store the last colors, and share
* the button border if the colors are the same as in the last
* invocation, but it probably is not worth the effort.
*/
return new BorderUIResource.CompoundBorderUIResource(
outer,
/* inner */ getMarginBorder());
}
/**
* Returns a shared MarginBorder.
*/
static Border getMarginBorder() // intentionally not public
{
/* Swing is not designed to be thread-safe, so there is no
* need to synchronize the access to the global variable.
*/
if (sharedMarginBorder == null)
sharedMarginBorder = new MarginBorder();
return sharedMarginBorder;
}
/**
* A border whose appearance depends on the state of
* the enclosed button.
*
* <p><img src="BasicBorders.ButtonBorder-1.png" width="300"
* height="170" alt="[A screen shot of this border]" />
*
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public static class ButtonBorder
extends AbstractBorder
implements Serializable, UIResource
{
/**
* Determined using the <code>serialver</code> tool
* of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
*/
static final long serialVersionUID = -157053874580739687L;
/**
* The color for drawing the shaded parts of the border.
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
*/
protected Color shadow;
/**
* The color for drawing the dark shaded parts of the border.
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
*/
protected Color darkShadow;
/**
* The color for drawing the highlighted parts of the border.
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
*/
protected Color highlight;
/**
* The color for drawing the bright highlighted parts of the border.
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
*/
protected Color lightHighlight;
/**
* Constructs a new border for drawing a button in the Basic
* look and feel.
*
* @param shadow the shadow color.
* @param darkShadow a darker variant of the shadow color.
* @param highlight the highlight color.
* @param lightHighlight a brighter variant of the highlight color.
*/
public ButtonBorder(Color shadow, Color darkShadow,
Color highlight, Color lightHighlight)
{
/* These colors usually come from the UIDefaults of the current
* look and feel. Use fallback values if the colors are not
* supplied. The API specification is silent about what
* behavior is expected for null colors, so users should not
* rely on this fallback (which is why it is not documented in
* the above Javadoc).
*/
this.shadow = (shadow != null) ? shadow : Color.gray;
this.darkShadow = (darkShadow != null) ? darkShadow : Color.black;
this.highlight = (highlight != null) ? highlight : Color.lightGray;
this.lightHighlight = (lightHighlight != null)
? lightHighlight
: Color.white;
}
/**
* Paints the ButtonBorder 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.
*
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel
*/
public void paintBorder(Component c, Graphics g,
int x, int y, int width, int height)
{
ButtonModel bmodel = null;
if (c instanceof AbstractButton)
bmodel = ((AbstractButton) c).getModel();
BasicGraphicsUtils.drawBezel(
g, x, y, width, height,
/* pressed */ (bmodel != null)
&& /* mouse button pressed */ bmodel.isPressed()
&& /* mouse inside */ bmodel.isArmed(),
/* default */ (c instanceof JButton)
&& ((JButton) c).isDefaultButton(),
shadow, darkShadow, highlight, lightHighlight);
}
/**
* Measures the width of this border.
*
* <p>Although the thickness of the actually painted border
* depends on the state of the enclosed component, this
* measurement always returns the same amount of pixels. Indeed,
* it would be rather confusing if a button was appearing to
* change its size depending on whether it is pressed or not.
*
* @param c the component whose border is to be measured.
*
* @return an Insets object whose <code>left</code>,
* <code>right</code>, <code>top</code> and
* <code>bottom</code> 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 getBorderInsets(c, null);
}
/**
* Measures the width of this border, storing the results into a
* pre-existing Insets object.
*
* <p>Although the thickness of the actually painted border
* depends on the state of the enclosed component, this
* measurement always returns the same amount of pixels. Indeed,
* it would be rather confusing if a button was appearing to
* change its size depending on whether it is pressed or not.
*
* @param insets an Insets object for holding the result values.
* After invoking this method, the <code>left</code>,
* <code>right</code>, <code>top</code> and
* <code>bottom</code> fields indicate the width of the
* border at the respective edge.
*
* @return the same object that was passed for <code>insets</code>.
*
* @see #getBorderInsets()
*/
public Insets getBorderInsets(Component c, Insets insets)
{
/* The exact amount has been determined using a test program
* that was run on the Sun reference implementation. With
* Apple/Sun JDK 1.3.1 on MacOS X 10.1.5, the result is
* [3, 3, 3, 3]. With Sun JDK 1.4.1_01 on Linux/x86, the
* result is [2, 3, 3, 3]. We use the values from the 1.4.1_01
* release.
*/
if (insets == null)
return new Insets(2, 3, 3, 3);
insets.top = 2;
insets.bottom = insets.left = insets.right = 3;
return insets;
}
}
public static class FieldBorder
{
public FieldBorder(Color shadow, Color darkShadow,
@ -53,9 +319,109 @@ public class BasicBorders
{
}
} // class FieldBorder
/**
* An invisible, but spacing border whose margin is determined
* by calling the <code>getMargin()</code> method of the enclosed
* component. If the enclosed component has no such method,
* this border will not occupy any space.
*
* <p><img src="BasicBorders.MarginBorder-1.png" width="325"
* height="200" alt="[An illustration that shows how MarginBorder
* determines its borders]" />
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public static class MarginBorder
extends AbstractBorder
implements Serializable, UIResource
{
} // class MarginBorder
/**
* Determined using the <code>serialver</code> tool
* of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
*/
static final long serialVersionUID = -3035848353448896090L;
/**
* Constructs a new MarginBorder.
*/
public MarginBorder()
{
}
/**
* Measures the width of this border.
*
* @param c the component whose border is to be measured.
*
* @return an Insets object whose <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> 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));
}
/**
* Determines the insets of this border by calling the
* <code>getMargin()</code> method of the enclosed component. The
* resulting margin will be stored into the the <code>left</code>,
* <code>right</code>, <code>top</code> and <code>bottom</code>
* fields of the passed <code>insets</code> parameter.
*
* <p>Unfortunately, <code>getMargin()</code> is not a method of
* {@link javax.swing.JComponent} or some other common superclass
* of things with margins. While reflection could be used to
* determine the existence of this method, this would be slow on
* many virtual machines. Therefore, the current implementation
* knows about {@link javax.swing.AbstractButton#getMargin()},
* {@link javax.swing.JPopupMenu#getMargin()}, and {@link
* javax.swing.JToolBar#getMargin()}. If <code>c</code> is an
* instance of a known class, the respective
* <code>getMargin()</code> method is called to determine the
* correct margin. Otherwise, a zero-width margin is returned.
*
* @param c the component whose border is to be measured.
*
* @return the same object that was passed for <code>insets</code>,
* but with changed fields.
*/
public Insets getBorderInsets(Component c, Insets insets)
{
Insets margin = null;
/* This is terrible object-oriented design. See the above Javadoc
* for an excuse.
*/
if (c instanceof AbstractButton)
margin = ((AbstractButton) c).getMargin();
else if (c instanceof JPopupMenu)
margin = ((JPopupMenu) c).getMargin();
else if (c instanceof JToolBar)
margin = ((JToolBar) c).getMargin();
if (margin == null)
insets.top = insets.left = insets.bottom = insets.right = 0;
else
{
insets.top = margin.top;
insets.left = margin.left;
insets.bottom = margin.bottom;
insets.right = margin.right;
}
return insets;
}
}
public static class MenuBarBorder
{
public MenuBarBorder(Color shadow, Color highlight)

View file

@ -74,14 +74,7 @@ public class BasicButtonUI extends ButtonUI
public Dimension getPreferredSize(JComponent c)
{
AbstractButton b = (AbstractButton)c;
Dimension d = BasicGraphicsUtils.getPreferredSize(b,
gap,
b.getText(),
b.getIcon(),
b.getVerticalAlignment(),
b.getHorizontalAlignment(),
b.getHorizontalTextPosition(),
b.getVerticalTextPosition());
Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
// System.out.println("^^^^^^^^^^^^^^^^^^^^^^ BASIC-PREF="+d + ",T="+b.text);
return d;
}
@ -99,7 +92,7 @@ public class BasicButtonUI extends ButtonUI
g.setFont(f);
FontMetrics fm = SwingUtilities.getFontMetrics(f);
FontMetrics fm = g.getFontMetrics(f);
Insets i = c.getInsets();
@ -198,7 +191,7 @@ public class BasicButtonUI extends ButtonUI
g.setFont(f);
FontMetrics fm = SwingUtilities.getFontMetrics(f);
FontMetrics fm = g.getFontMetrics(f);
g.setColor(c.isEnabled() ? textColor : disabledTextColor);

View file

@ -57,15 +57,7 @@ public class BasicCheckBoxUI extends BasicRadioButtonUI
public Dimension getPreferredSize(JComponent c)
{
AbstractButton b = (AbstractButton)c;
Dimension d = BasicGraphicsUtils.getPreferredSize(b,
gap,
b.getText(),
b.getIcon(),
b.getVerticalAlignment(),
b.getHorizontalAlignment(),
b.getHorizontalTextPosition(),
b.getVerticalTextPosition());
Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
//System.out.println("^^^^^^^^^^^^^^^^^^^^^^ BASIC-PREF="+d + ",T="+b.text);
return d;
}

View file

@ -1,5 +1,5 @@
/* BasicGraphicsUtils.java
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -35,81 +35,602 @@ 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.plaf.basic;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.*;
import javax.swing.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import javax.swing.AbstractButton;
import javax.swing.SwingUtilities;
/**
* A utility class providing commonly used drawing and measurement
* routines.
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class BasicGraphicsUtils
{
public static Dimension getPreferredSize(JComponent b,
int gap,
String text,
Icon icon,
int va,
int ha,
int htp,
int vtp)
{
/**
* Constructor. It is utterly unclear why this class should
* be constructable, but this is what the API specification
* says.
*/
public BasicGraphicsUtils()
{
}
/**
* Draws a rectangle that appears etched into the surface, given
* four colors that are used for drawing.
*
* <p><img src="BasicGraphicsUtils-1.png" width="360"
* height="200" alt="[An illustration that shows which pixels
* get painted in what color]" />
*
* @param g the graphics into which the rectangle is drawn.
* @param x the x coordinate of the rectangle.
* @param y the y coordinate of the rectangle.
* @param width the width of the rectangle in pixels.
* @param height the height of the rectangle in pixels.
*
* @param shadow the color that will be used for painting
* the outer side of the top and left edges.
*
* @param darkShadow the color that will be used for painting
* the inner side of the top and left edges.
*
* @param highlight the color that will be used for painting
* the inner side of the bottom and right edges.
*
* @param lightHighlight the color that will be used for painting
* the outer side of the bottom and right edges.
*
* @see #getEtchedInsets()
* @see javax.swing.border.EtchedBorder
*/
public static void drawEtchedRect(Graphics g,
int x, int y, int width, int height,
Color shadow, Color darkShadow,
Color highlight, Color lightHighlight)
{
Color oldColor;
int x2, y2;
oldColor = g.getColor();
x2 = x + width - 1;
y2 = y + height - 1;
try
{
JComponent c = b;
// this is a staight copy from BasicButtonUI.paint()
//
Rectangle tr = new Rectangle();
Rectangle ir = new Rectangle();
Rectangle vr = new Rectangle();
/* To understand this code, it might be helpful to look at the
* image "BasicGraphicsUtils-1.png" that is included with the
* JavaDoc. The file is located in the "doc-files" subdirectory.
*
* (x2, y2) is the coordinate of the most right and bottom pixel
* to be painted.
*/
g.setColor(shadow);
g.drawLine(x, y, x2 - 1, y); // top, outer
g.drawLine(x, y + 1, x, y2 - 1); // left, outer
Font f = c.getFont();
g.setColor(darkShadow);
g.drawLine(x + 1, y + 1, x2 - 2, y + 1); // top, inner
g.drawLine(x + 1, y + 2, x + 1, y2 - 2); // left, inner
g.setColor(highlight);
g.drawLine(x + 1, y2 - 1, x2 - 1, y2 - 1); // bottom, inner
g.drawLine(x2 - 1, y + 1, x2 - 1, y2 - 2); // right, inner
FontMetrics fm = SwingUtilities.getFontMetrics(f);
g.setColor(lightHighlight);
g.drawLine(x, y2, x2, y2); // bottom, outer
g.drawLine(x2, y, x2, y2 - 1); // right, outer
}
finally
{
g.setColor(oldColor);
}
}
/**
* Determines the width of the border that gets painted by
* {@link #drawEtchedRect}.
*
* @return an <code>Insets</code> object whose <code>top</code>,
* <code>left</code>, <code>bottom</code> and
* <code>right</code> field contain the border width at the
* respective edge in pixels.
*/
public static Insets getEtchedInsets()
{
return new Insets(2, 2, 2, 2);
}
Insets i = c.getInsets();
vr.x = i.left;
vr.y = i.top;
vr.width = b.getWidth() - (i.right + i.left);
vr.height = b.getHeight() - (i.bottom + i.top);
/**
* Draws a rectangle that appears etched into the surface, given
* two colors that are used for drawing.
*
* <p><img src="BasicGraphicsUtils-2.png" width="360"
* height="200" alt="[An illustration that shows which pixels
* get painted in what color]" />
*
* @param g the graphics into which the rectangle is drawn.
* @param x the x coordinate of the rectangle.
* @param y the y coordinate of the rectangle.
* @param width the width of the rectangle in pixels.
* @param height the height of the rectangle in pixels.
*
* @param shadow the color that will be used for painting the outer
* side of the top and left edges, and for the inner side of
* the bottom and right ones.
*
* @param highlight the color that will be used for painting the
* inner side of the top and left edges, and for the outer
* side of the bottom and right ones.
*
* @see #getGrooveInsets()
* @see javax.swing.border.EtchedBorder
*/
public static void drawGroove(Graphics g,
int x, int y, int width, int height,
Color shadow, Color highlight)
{
/* To understand this, it might be helpful to look at the image
* "BasicGraphicsUtils-2.png" that is included with the JavaDoc,
* and to compare it with "BasicGraphicsUtils-1.png" which shows
* the pixels painted by drawEtchedRect. These image files are
* located in the "doc-files" subdirectory.
*/
drawEtchedRect(g, x, y, width, height,
/* outer topLeft */ shadow,
/* inner topLeft */ highlight,
/* inner bottomRight */ shadow,
/* outer bottomRight */ highlight);
}
// System.out.println(" VIEW-RECT-BUTTON="+vr+", insets="+i);
String tt = SwingUtilities.layoutCompoundLabel(b,
fm,
text,
icon,
va,
ha,
vtp,
htp,
vr,
ir,
tr,
gap);
Rectangle r = ir.union(tr);
Insets insets = b.getInsets();
r.width += insets.left + insets.right;
r.height += insets.top + insets.bottom;
/**
* Determines the width of the border that gets painted by
* {@link #drawGroove}.
*
* @return an <code>Insets</code> object whose <code>top</code>,
* <code>left</code>, <code>bottom</code> and
* <code>right</code> field contain the border width at the
* respective edge in pixels.
*/
public static Insets getGrooveInsets()
{
return new Insets(2, 2, 2, 2);
}
// System.out.println("COMPUTED SIZE FOR PREF_SIZE="+r);
/**
* Draws a border that is suitable for buttons of the Basic look and
* feel.
*
* <p><img src="BasicGraphicsUtils-3.png" width="500"
* height="300" alt="[An illustration that shows which pixels
* get painted in what color]" />
*
* @param g the graphics into which the rectangle is drawn.
* @param x the x coordinate of the rectangle.
* @param y the y coordinate of the rectangle.
* @param width the width of the rectangle in pixels.
* @param height the height of the rectangle in pixels.
*
* @param isPressed <code>true</code> to draw the button border
* with a pressed-in appearance; <code>false</code> for
* normal (unpressed) appearance.
*
* @param isDefault <code>true</code> to draw the border with
* the appearance it has when hitting the enter key in a
* dialog will simulate a click to this button;
* <code>false</code> for normal appearance.
*
* @param shadow the shadow color.
* @param darkShadow a darker variant of the shadow color.
* @param highlight the highlight color.
* @param lightHighlight a brighter variant of the highlight color.
*/
public static void drawBezel(Graphics g,
int x, int y, int width, int height,
boolean isPressed, boolean isDefault,
Color shadow, Color darkShadow,
Color highlight, Color lightHighlight)
{
Color oldColor = g.getColor();
return r.getSize();
/* To understand this, it might be helpful to look at the image
* "BasicGraphicsUtils-3.png" that is included with the JavaDoc,
* and to compare it with "BasicGraphicsUtils-1.png" which shows
* the pixels painted by drawEtchedRect. These image files are
* located in the "doc-files" subdirectory.
*/
try
{
if ((isPressed == false) && (isDefault == false))
{
drawEtchedRect(g, x, y, width, height,
lightHighlight, highlight,
shadow, darkShadow);
}
if ((isPressed == true) && (isDefault == false))
{
g.setColor(shadow);
g.drawRect(x + 1, y + 1, width - 2, height - 2);
}
if ((isPressed == false) && (isDefault == true))
{
g.setColor(darkShadow);
g.drawRect(x, y, width - 1, height - 1);
drawEtchedRect(g, x + 1, y + 1, width - 2, height - 2,
lightHighlight, highlight,
shadow, darkShadow);
}
if ((isPressed == true) && (isDefault == true))
{
g.setColor(darkShadow);
g.drawRect(x, y, width - 1, height - 1);
g.setColor(shadow);
g.drawRect(x + 1, y + 1, width - 3, height - 3);
}
}
finally
{
g.setColor(oldColor);
}
}
/**
* Draws a rectangle that appears lowered into the surface, given
* four colors that are used for drawing.
*
* <p><img src="BasicGraphicsUtils-4.png" width="360"
* height="200" alt="[An illustration that shows which pixels
* get painted in what color]" />
*
* <p><strong>Compatibility with the Sun reference
* implementation:</strong> The Sun reference implementation seems
* to ignore the <code>x</code> and <code>y</code> arguments, at
* least in JDK 1.3.1 and 1.4.1_01. The method always draws the
* rectangular area at location (0, 0). A bug report has been filed
* with Sun; its &#x201c;bug ID&#x201d; is 4880003. The GNU Classpath
* implementation behaves correctly, thus not replicating this bug.
*
* @param g the graphics into which the rectangle is drawn.
* @param x the x coordinate of the rectangle.
* @param y the y coordinate of the rectangle.
* @param width the width of the rectangle in pixels.
* @param height the height of the rectangle in pixels.
*
* @param shadow the color that will be used for painting
* the inner side of the top and left edges.
*
* @param darkShadow the color that will be used for painting
* the outer side of the top and left edges.
*
* @param highlight the color that will be used for painting
* the inner side of the bottom and right edges.
*
* @param lightHighlight the color that will be used for painting
* the outer side of the bottom and right edges.
*/
public static void drawLoweredBezel(Graphics g,
int x, int y, int width, int height,
Color shadow, Color darkShadow,
Color highlight, Color lightHighlight)
{
/* Like drawEtchedRect, but swapping darkShadow and shadow.
*
* To understand this, it might be helpful to look at the image
* "BasicGraphicsUtils-4.png" that is included with the JavaDoc,
* and to compare it with "BasicGraphicsUtils-1.png" which shows
* the pixels painted by drawEtchedRect. These image files are
* located in the "doc-files" subdirectory.
*/
drawEtchedRect(g, x, y, width, height,
darkShadow, shadow,
highlight, lightHighlight);
}
/**
* Draws a String at the given location, underlining the first
* occurence of a specified character. The algorithm for determining
* the underlined position is not sensitive to case. If the
* character is not part of <code>text</code>, the text will be
* drawn without underlining. Drawing is performed in the current
* color and font of <code>g</code>.
*
* <p><img src="BasicGraphicsUtils-5.png" width="500"
* height="100" alt="[An illustration showing how to use the
* method]" />
*
* @param g the graphics into which the String is drawn.
*
* @param text the String to draw.
*
* @param underlinedChar the character whose first occurence in
* <code>text</code> will be underlined. It is not clear
* why the API specification declares this argument to be
* of type <code>int</code> instead of <code>char</code>.
* While this would allow to pass Unicode characters outside
* Basic Multilingual Plane 0 (U+0000 .. U+FFFE), at least
* the GNU Classpath implementation does not underline
* anything if <code>underlinedChar</code> is outside
* the range of <code>char</code>.
*
* @param x the x coordinate of the text, as it would be passed to
* {@link java.awt.Graphics#drawString(java.lang.String,
* int, int)}.
*
* @param y the y coordinate of the text, as it would be passed to
* {@link java.awt.Graphics#drawString(java.lang.String,
* int, int)}.
*/
public static void drawString(Graphics g, String text,
int underlinedChar, int x, int y)
{
int index = -1;
/* It is intentional that lower case is used. In some languages,
* the set of lowercase characters is larger than the set of
* uppercase ones. Therefore, it is good practice to use lowercase
* for such comparisons (which really means that the author of this
* code can vaguely remember having read some Unicode techreport
* with this recommendation, but is too lazy to look for the URL).
*/
if ((underlinedChar >= 0) || (underlinedChar <= 0xffff))
index = text.toLowerCase().indexOf(
Character.toLowerCase((char) underlinedChar));
drawStringUnderlineCharAt(g, text, index, x, y);
}
/**
* Draws a String at the given location, underlining the character
* at the specified index. Drawing is performed in the current color
* and font of <code>g</code>.
*
* <p><img src="BasicGraphicsUtils-5.png" width="500"
* height="100" alt="[An illustration showing how to use the
* method]" />
*
* @param g the graphics into which the String is drawn.
*
* @param text the String to draw.
*
* @param underlinedIndex the index of the underlined character in
* <code>text</code>. If <code>underlinedIndex</code> falls
* outside the range <code>[0, text.length() - 1]</code>, the
* text will be drawn without underlining anything.
*
* @param x the x coordinate of the text, as it would be passed to
* {@link java.awt.Graphics#drawString(java.lang.String,
* int, int)}.
*
* @param y the y coordinate of the text, as it would be passed to
* {@link java.awt.Graphics#drawString(java.lang.String,
* int, int)}.
*
* @since 1.4
*/
public static void drawStringUnderlineCharAt(Graphics g, String text,
int underlinedIndex,
int x, int y)
{
Graphics2D g2;
Rectangle2D.Double underline;
FontRenderContext frc;
FontMetrics fmet;
LineMetrics lineMetrics;
Font font;
TextLayout layout;
double underlineX1, underlineX2;
boolean drawUnderline;
int textLength;
textLength = text.length();
if (textLength == 0)
return;
drawUnderline = (underlinedIndex >= 0) && (underlinedIndex < textLength);
if (!(g instanceof Graphics2D))
{
/* Fall-back. This is likely to produce garbage for any text
* containing right-to-left (Hebrew or Arabic) characters, even
* if the underlined character is left-to-right.
*/
g.drawString(text, x, y);
if (drawUnderline)
{
fmet = g.getFontMetrics();
g.fillRect(
/* x */ x + fmet.stringWidth(text.substring(0, underlinedIndex)),
/* y */ y + fmet.getDescent() - 1,
/* width */ fmet.charWidth(text.charAt(underlinedIndex)),
/* height */ 1);
}
return;
}
public static void drawString(Graphics g,
String text,
int underlinedChar,
int x,
int y)
g2 = (Graphics2D) g;
font = g2.getFont();
frc = g2.getFontRenderContext();
lineMetrics = font.getLineMetrics(text, frc);
layout = new TextLayout(text, font, frc);
/* Draw the text. */
layout.draw(g2, x, y);
if (!drawUnderline)
return;
underlineX1 = x + layout.getLogicalHighlightShape(
underlinedIndex, underlinedIndex).getBounds2D().getX();
underlineX2 = x + layout.getLogicalHighlightShape(
underlinedIndex + 1, underlinedIndex + 1).getBounds2D().getX();
underline = new Rectangle2D.Double();
if (underlineX1 < underlineX2)
{
g.drawString(text, x, y);
underline.x = underlineX1;
underline.width = underlineX2 - underlineX1;
}
else
{
underline.x = underlineX2;
underline.width = underlineX1 - underlineX2;
}
underline.height = lineMetrics.getUnderlineThickness();
underline.y = lineMetrics.getUnderlineOffset();
if (underline.y == 0)
{
/* Some fonts do not specify an underline offset, although they
* actually should do so. In that case, the result of calling
* lineMetrics.getUnderlineOffset() will be zero. Since it would
* look very ugly if the underline was be positioned immediately
* below the baseline, we check for this and move the underline
* below the descent, as shown in the following ASCII picture:
*
* ##### ##### #
* # # # #
* # # # #
* # # # #
* ##### ###### ---- baseline (0)
* #
* #
* ------------------###----------- lineMetrics.getDescent()
*/
underline.y = lineMetrics.getDescent();
}
underline.y += y;
g2.fill(underline);
}
/**
* Draws a rectangle, simulating a dotted stroke by painting only
* every second pixel along the one-pixel thick edge. The color of
* those pixels is the current color of the Graphics <code>g</code>.
* Any other pixels are left unchanged.
*
* <p><img src="BasicGraphicsUtils-7.png" width="360"
* height="200" alt="[An illustration that shows which pixels
* get painted]" />
*
* @param g the graphics into which the rectangle is drawn.
* @param x the x coordinate of the rectangle.
* @param y the y coordinate of the rectangle.
* @param width the width of the rectangle in pixels.
* @param height the height of the rectangle in pixels.
*/
public static void drawDashedRect(Graphics g,
int x, int y, int width, int height)
{
int right = x + width - 1;
int bottom = y + height - 1;
/* Draw the top and bottom edge of the dotted rectangle. */
for (int i = x; i <= right; i += 2)
{
g.drawLine(i, y, i, y);
g.drawLine(i, bottom, i, bottom);
}
/* Draw the left and right edge of the dotted rectangle. */
for (int i = y; i <= bottom; i += 2)
{
g.drawLine(x, i, x, i);
g.drawLine(right, i, right, i);
}
}
/**
* Determines the preferred width and height of an AbstractButton,
* given the gap between the button&#x2019;s text and icon.
*
* @param b the button whose preferred size is determined.
*
* @param textIconGap the gap between the button&#x2019;s text and
* icon.
*
* @return a <code>Dimension</code> object whose <code>width</code>
* and <code>height</code> fields indicate the preferred
* extent in pixels.
*
* @see javax.swing.SwingUtilities#layoutCompoundLabel
*/
public static Dimension getPreferredButtonSize(AbstractButton b,
int textIconGap)
{
Rectangle contentRect;
Rectangle viewRect;
Rectangle iconRect = new Rectangle();
Rectangle textRect = new Rectangle();
Insets insets = b.getInsets();
/* For determining the ideal size, do not assume a size restriction. */
viewRect = new Rectangle(0, 0,
/* width */ Integer.MAX_VALUE,
/* height */ Integer.MAX_VALUE);
/* java.awt.Toolkit.getFontMetrics is deprecated. However, it
* seems not obvious how to get to the correct FontMetrics object
* otherwise. The real problem probably is that the method
* javax.swing.SwingUtilities.layoutCompundLabel should take a
* LineMetrics, not a FontMetrics argument. But fixing this that
* would change the public API.
*/
SwingUtilities.layoutCompoundLabel(
b, // for the component orientation
b.getToolkit().getFontMetrics(b.getFont()), // see comment above
b.getText(),
b.getIcon(),
b.getVerticalAlignment(),
b.getHorizontalAlignment(),
b.getVerticalTextPosition(),
b.getHorizontalTextPosition(),
viewRect, iconRect, textRect,
textIconGap);
/* +------------------------+ +------------------------+
* | | | |
* | ICON | | CONTENTCONTENTCONTENT |
* | TEXTTEXTTEXT | --> | CONTENTCONTENTCONTENT |
* | TEXTTEXTTEXT | | CONTENTCONTENTCONTENT |
* +------------------------+ +------------------------+
*/
contentRect = textRect.union(iconRect);
return new Dimension(insets.left + contentRect.width + insets.right,
insets.top + contentRect.height + insets.bottom);
}
}

View file

@ -65,6 +65,10 @@ public class BasicLabelUI extends LabelUI
public Dimension getPreferredSize(JComponent c)
{
JLabel b = (JLabel)c;
/*
We cannot use this method because it is not part of the
official Swing API.
Dimension d = BasicGraphicsUtils.getPreferredSize(b,
gap,
b.getText(),
@ -74,7 +78,8 @@ public class BasicLabelUI extends LabelUI
b.getHorizontalTextPosition(),
b.getVerticalTextPosition());
System.out.println("JLABEL->^^^^^^^^^^^^^^^^^^^^^^ BASIC-PREF="+d + ",T="+b.getText());
return d;
*/
return new Dimension(100, 30);
}
@ -90,7 +95,7 @@ public class BasicLabelUI extends LabelUI
g.setFont(f);
FontMetrics fm = SwingUtilities.getFontMetrics(f);
FontMetrics fm = g.getFontMetrics(f);
Insets i = c.getInsets();

View file

@ -60,14 +60,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
public Dimension getPreferredSize(JComponent c)
{
AbstractButton b = (AbstractButton)c;
Dimension d = BasicGraphicsUtils.getPreferredSize(b,
gap,
b.getText(),
b.getIcon(),
b.getVerticalAlignment(),
b.getHorizontalAlignment(),
b.getHorizontalTextPosition(),
b.getVerticalTextPosition());
Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
// and add a little something for the circles:

View file

@ -58,14 +58,7 @@ public class BasicToggleButtonUI extends BasicButtonUI
public Dimension getPreferredSize(JComponent c)
{
AbstractButton b = (AbstractButton)c;
Dimension d = BasicGraphicsUtils.getPreferredSize(b,
gap,
b.getText(),
b.getIcon(),
b.getVerticalAlignment(),
b.getHorizontalAlignment(),
b.getHorizontalTextPosition(),
b.getVerticalTextPosition());
Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
//System.out.println("^^^^^^^^^^^^^^^^^^^^^^ BASIC-PREF="+d + ",T="+b.text);
return d;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB