| I l@ve RuBoard | 
	 | 
13.3 Swing BordersThe following sections discuss Swing's built-in border classes in detail. 13.3.1 The BevelBorder and SoftBevelBorder ClassesA bevel is another name for a slanted edge. The BevelBorder class can be used to simulate a raised or lowered edge with a slant surrounding the component, similar to the appearance of a button. The default bevel edge is two pixels wide on all sides. Figure 13-4 shows two bevel borders, the first raised and the second lowered. Figure 13-4. Raised and lowered bevel borders![]() Notice how the border creates the illusion of three dimensions. The bevel border simulates a light source above and to the left of the object (this light source location must be consistent for all 3D components in order to be effective). The border is then drawn with four colors: an outer and inner highlight color and an outer and inner shadow color. The highlight colors represent the two surfaces of the bevel facing toward the light while the shadow colors represent the surfaces facing away from the light. Figure 13-5 shows how a bevel border uses the highlight and shadow colors. Figure 13-5. The four colors of a bevel border![]() When the bevel is raised, the top and left sides of the border are highlighted, and the bottom and right sides of the border are shadowed. This presents the appearance of the surface protruding above the background. When the bevel is lowered, the highlighted and shadowed surfaces are reversed, and the border appears to sink into the background. A bevel border is two pixels wide on all sides. The inner color represents the inner pixels for the border; the outer color represents the outer pixels. The beveled border in Swing has a subclass, SoftBevelBorder, that can be used to simulate a subtle raised or lowered edge around a component. In fact, the only difference from the regular BevelBorder is that the soft beveled edge is slightly thinner on two of its four sides and provides for small rounded corners. Figure 13-6 shows a pair of soft bevel borders; if your eyes are really good, you may be able to tell the difference between these and the plain bevel borders. Figure 13-6. Soft bevel borders in Swing![]() 13.3.1.1 PropertiesTable 13-2 shows the properties of BevelBorder and SoftBevelBorder. The bevelType property shows whether the border appears raised or lowered. The borderOpaque property is true by default for a bevel border and false for a soft bevel border. 
 13.3.1.2 ConstantsThe BevelBorder and SoftBevelBorder classes define two constants used to initialize the bevelType property, as shown in Table 13-3. 
 13.3.1.3 Default colorsIf colors are not specified in the constructor, they are derived from the component using the border, as shown in Table 13-4. In this table, background refers to the component's background color. 
 13.3.1.4 Constructors
 In the constructors with two Color arguments, the given colors set the highlightInner and shadowOuter properties. highlightOuter is set to highlight.darker( ), and shadowInner is set to shadow.brighter( ). 13.3.1.5 Methods
 13.3.1.6 Changing borders on the flyHere is a short program that creates four labels. Each label draws a bevel border around itself when the mouse pointer enters the component's region and erases it when the mouse leaves the region. This kind of "rollover" effect has become a popular feature in some applications' toolbars. Modifying the program to use soft bevel borders would be trivial. //  BevelExample.java
//
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class BevelExample extends JPanel {
    BevelBorder bevel;
    EmptyBorder empty;
    JLabel label[] = new JLabel[4];
    public BevelExample( ) {
        super(true);
        setLayout(new GridLayout(1, 4));
        bevel = new BevelBorder(BevelBorder.RAISED);
        empty = new EmptyBorder(5, 5, 5, 5);
        label[0] = new JLabel("Home");
        label[1] = new JLabel("Back");
        label[2] = new JLabel("Forward");
        label[3] = new JLabel("Stop");
        for (int i = 0; i < label.length; i++) {
            label[i].setHorizontalAlignment(JLabel.CENTER);
            label[i].addMouseListener(new RolloverListener( ));
            label[i].setBorder(empty);
            add(label[i]);
        }
    }
    public static void main(String s[]) {
         JFrame frame = new JFrame("Bevel Border");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setSize(400, 100);
         frame.setContentPane(new BevelExample( ));
         frame.setVisible(true);
    }
    // Inner class to respond to mouse events for the "rollover" effect
    class RolloverListener extends MouseAdapter {
        public void mouseEntered(MouseEvent e) {
            ((JLabel)e.getComponent( )).setBorder(bevel);
            repaint( );
        }
        public void mouseExited(MouseEvent e) {
            ((JLabel)e.getComponent( )).setBorder(empty);
            repaint( );
        }
        public void mouseClicked(MouseEvent e) {
            String text = ((JLabel)e.getComponent( )).getText( );
            System.out.println("You clicked " + text + "!");
        }
    }
}
Figure 13-7 shows the results of our example. Figure 13-7. Working with bevel borders![]() 13.3.2 The Empty Border ClassThe EmptyBorder class is used to place empty space around a component. The size of the space on each side is defined by the border's insets, which are set in the constructor. Figure 13-8 shows an empty border with 20 pixels on all sides surrounding a JLabel. (Note that we used two other borders to denote the boundaries of the EmptyBorder.) Figure 13-8. An empty border with two etched borders surrounding it![]() 13.3.2.1 PropertiesTable 13-5 shows the properties of the EmptyBorder class. 
 13.3.2.2 Constructors
 13.3.2.3 Method
 13.3.3 The EtchedBorder ClassAn etched border is a single etching that surrounds the target component. The etching consists of adjacent lines of two colors, a highlight and a shadow, and can be raised or lowered. Like bevel borders, etched borders render themselves by simulating a light source above and to the left. The highlight is the color of the etching that faces the light source while the shadow is the color of the etching that faces away from the light source. An etched border is shown in Figure 13-9. Figure 13-9. A lowered etched border in Swing![]() An etched border is very similar to a bevel border. By carefully manipulating the colors, you can create an EtchedBorder from a BevelBorder. 13.3.3.1 PropertiesThe properties for the EtchedBorder class are shown in Table 13-6. The borderOpaque property always returns true, indicating that this border paints over all of its allocated pixels. The etchType tells whether the etch appears raised or lowered. Finally, the highlightColor and shadowColor properties indicate the two colors used to simulate the etching. If no values are given, brighter and darker variations of the background color of the component are used for highlightColor and shadowColor, respectively. 
 13.3.3.2 ConstantsEtchedBorder contains two constants used to initialize the etchType property, as shown in Table 13-7. 
 13.3.3.3 Constructors
 13.3.3.4 Miscellaneous
 13.3.4 The LineBorder ClassThe LineBorder class creates a border consisting of a line of arbitrary thickness around the component. Unlike the beveled or etched borders, the line is a single color and is not shaded. Since SDK 1.3, you can specify that the border use (very subtly) rounded corners. Figure 13-10 shows two different line borders, each with a different thicknesses. Figure 13-10. Line borders in Swing![]() 13.3.4.1 PropertiesThe properties for the LineBorder object are shown in Table 13-8. The borderOpaque property always returns true, indicating that this border paints over all of its allocated pixels. The others describe the way it will be drawn; all are read-only and can be set only during construction. 
 13.3.4.2 Constructors
 13.3.4.3 Methods
 13.3.4.4 MiscellaneousThe LineBorder class contains two shortcut methods allowing you to reuse objects for certain commonly used kinds of borders. These methods reduce garbage collection by returning the same object each time they are called. (The ability to safely and easily support this kind of shared object reuse is one of the major advantages of writing immutable classes like LineBorder.) 
 13.3.5 The MatteBorder ClassIn art and photography, a mat is often used to offset a picture from its frame. In Swing, matte[1] borders perform the same function, separating a component from everything else. A matte border in Swing can be either a solid color or a repeated image icon. The color or icon fills the entire space reserved by the border's insets. 
 With a MatteBorder, you have the choice of constructing the object with either a Color or an Icon. If you choose a color, the color flood-fills the entire space reserved for the border. If you use an icon, the icon tiles or wallpapers itself throughout the entire area of the MatteBorder. Figure 13-11 shows both kinds of MatteBorder. Figure 13-11. Various matte borders in Swing![]() 13.3.5.1 PropertiesMatteBorder extends the EmptyBorder class. The borderOpaque property can be either true or false, depending on how the border is used. If the MatteBorder is drawn exclusively with a solid color, then the border is opaque, and the property has a value of true. If the border is used with an image, the image may contain transparency, and the property has a value of false. (See Table 13-9.) 
 13.3.5.2 Constructors
 13.3.5.3 Methods
 13.3.5.4 Two kinds of matte bordersHere is a program that displays the two types of matte borders from Figure 13-11. //  MatteExample.java
//
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class MatteExample extends JPanel {
    public MatteExample( ) {
        super(true);
        this.setLayout(new GridLayout(1, 2, 5, 5));
        JLabel label1 = new JLabel("Matte Border");
        JLabel label2 = new JLabel("Matte Border (Icon)");
        label1.setHorizontalAlignment(JLabel.CENTER);
        label2.setHorizontalAlignment(JLabel.CENTER);
        Icon icon = new ImageIcon("plant.gif");
        MatteBorder matte = new MatteBorder(35, 35, 35, 35, Color.blue);
        MatteBorder matteicon = new MatteBorder(35, 35, 35, 35, icon);
        label1.setBorder(matte);
        label2.setBorder(matteicon);
        add(label1);
        add(label2);
    }
    public static void main(String s[]) {
         JFrame frame = new JFrame("Matte Borders");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setSize(500, 200);
         frame.setContentPane(new MatteExample( ));
         frame.setVisible(true);
    }
}
13.3.6 The TitledBorder ClassThe TitledBorder class takes an arbitrary border and adds a descriptive string to it. This title string can be placed in one of six different positions around the component and can be set to appear above, below, or overlaid on the border. In addition, you can specify the font and color of the title string. Figure 13-12 enumerates all of the explicit title positions and justifications available. 
 You can use any style of border in conjunction with a TitledBorder by setting the TitledBorder's own border property. For example, the borders in Figure 13-12 are used in conjunction with a BevelBorder. The default border style, however, is an EtchedBorder. A titled, etched border (with the title at the top leading corner) has a strong tradition of being used in many applications to group a set of related user-interface elements visually inside of a larger window. Figure 13-12. Title positions and justifications![]() 13.3.6.1 PropertiesThe properties for the TitledBorder class are given in Table 13-10. The border property contains the border that is being titled. It can be any border that implements the Border interface. The read-only borderOpaque property always returns false; the titled border does not color all of its pixels. The title property holds the string that is displayed with this border. titleColor is the string's color, titleFont represents its font, size, and style. titleJustification and titlePosition tell where the title appears in relation to the component and the border. See Table 13-11 and Table 13-12 for their values. 
 
 
 13.3.6.2 Constructors
 13.3.6.3 Miscellaneous
 13.3.6.4 Using a titled borderHere is a short program that creates the image displayed in Figure 13-13: //  TitledExample.java
//
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class TitledExample extends JPanel {
    public TitledExample( ) {
        super(true);
        this.setLayout(new GridLayout(1, 1, 5, 5));
        JLabel label = new JLabel("Titled Border");
        label.setHorizontalAlignment(JLabel.CENTER);
        TitledBorder titled = new TitledBorder("Title");
        label.setBorder(titled);
        add(label);
    }
    public static void main(String s[]) {
         JFrame frame = new JFrame("Borders");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setSize(200, 100);
         frame.setContentPane(new TitledExample( ));
         frame.setVisible(true);
    }
}
Figure 13-13. A simple title border![]() 13.3.7 The CompoundBorder ClassYou can combine two borders to create more elaborate displays with the CompoundBorder class. The insets of both borders are added together to form the insets of the resulting compound border object. The component renders the outside border first, followed by the inside border. You can compound borders recursively so that any number of borders can be embedded inside of a CompoundBorder object: CompoundBorder comp = new CompoundBorder(new CompoundBorder(new EtchedBorder( ),
                                         new EmptyBorder(10, 10, 10, 10)),
                      new MatteBorder(20, 20, 20, 20, Color.red));
The preceding code yields the border in Figure 13-14. Figure 13-14. A compound border![]() 13.3.7.1 PropertiesTable 13-13 lists the properties of the CompoundBorder class. The insideBorder and outsideBorder properties hold the borders that are combined. If both of the borders in the compound border are opaque, the borderOpaque property is true. Otherwise, the property is false. 
 13.3.7.2 Constructors
 13.3.7.3 Miscellaneous
 13.3.8 The BorderFactory ClassThe BorderFactory class (which is in the javax.swing package) allows you to call various static methods to create borders. Instead of declaring new instances for each border, the factory class attempts to reuse previously defined (cached) borders, thus saving memory. It's a good idea to get in the habit of using this factory if you create a lot of borders in your application. Currently, only a few borders are actually cached. But in future releases, additional border caching may be added to this class. The fact that most border classes are immutable (i.e., they contain no mutator methods that would allow them to be changed) is an excellent design choice that enables this kind of instance sharing safely and easily even in a multithreaded environment like Java. 13.3.8.1 Methods
  | 
| I l@ve RuBoard | 
           |