Wednesday, October 21, 2009

13.4 Creating Your Own Border




I l@ve RuBoard










13.4 Creating Your Own Border



Creating
your own border is simple when you extend the
AbstractBorder
class. You need to define three things: how to draw the border,
whether it is opaque, and what its insets are. To accomplish this,
you must implement paintBorder( ), both
isBorderOpaque( ) methods, and
getBorderInsets( ). The hard part of coming up
with your own border is doing something creative with the
Graphics primitives in the paintBorder( ) method. A reminder: make sure that you
paint only in the insets region
that you define for yourself. Otherwise, you could be painting over
the component you intend to border.



Let's take a look at a simple border:



// CurvedBorder.java
//
import java.awt.*;
import javax.swing.border.*;

public class CurvedBorder extends AbstractBorder
{
private Color wallColor = Color.gray;
private int sinkLevel = 10;

public CurvedBorder( ) { }
public CurvedBorder(int sinkLevel) { this.sinkLevel = sinkLevel; }
public CurvedBorder(Color wall) { this.wallColor = wall; }
public CurvedBorder(int sinkLevel, Color wall) {
this.sinkLevel = sinkLevel;
this.wallColor = wall;
}

public void paintBorder(Component c, Graphics g, int x, int y, int w, int h)
{
g.setColor(getWallColor( ));

// Paint a tall wall around the component.
for (int i = 0; i < sinkLevel; i++) {
g.drawRoundRect(x+i, y+i, w-i-1, h-i-1, sinkLevel-i, sinkLevel);
g.drawRoundRect(x+i, y+i, w-i-1, h-i-1, sinkLevel, sinkLevel-i);
g.drawRoundRect(x+i, y, w-i-1, h-1, sinkLevel-i, sinkLevel);
g.drawRoundRect(x, y+i, w-1, h-i-1, sinkLevel, sinkLevel-i);
}
}

public Insets getBorderInsets(Component c) {
return new Insets(sinkLevel, sinkLevel, sinkLevel, sinkLevel);
}
public Insets getBorderInsets(Component c, Insets i) {
i.left = i.right = i.bottom = i.top = sinkLevel;
return i;
}
public boolean isBorderOpaque( ) { return true; }
public int getSinkLevel( ) { return sinkLevel; }
public Color getWallColor( ) { return wallColor; }
}


This border draws round rectangles in succession around the
component. The rectangles are offset from each other so that it
appears that the component is depressed into the surface. The
sinkLevel property defines how
"deep" the depression should
appear. Note that we define the border insets to match the
sinkLevel property. We draw four round rectangles
on each pass, instead of just one � this ensures that each
pixel is filled between rectangles, which won't be
the case if we use just one. (If you want to see what we mean, try
commenting out some of the drawRoundRect( )
calls.) Finally, the wallColor property specifies
the border's color.



Here is an excerpt from the source that you can use to surround a
slider with this border. Figure 13-15 shows the
result.



JSlider mySlider = new JSlider( );
mySlider.setMajorTickSpacing(20);
mySlider.setMinorTickSpacing(10);
mySlider.setPaintTicks(true);
mySlider.setPaintLabels(true);

CurvedBorder border = new CurvedBorder(10, Color.darkGray);
mySlider.setBorder(border);



Figure 13-15. A custom curved border









    I l@ve RuBoard



    No comments: