Every JComponent
can have one or more borders.
Borders are incredibly useful objects that, while not themselves components,
know how to draw the edges of Swing components. Borders are useful not only
for drawing lines and fancy edges, but also for providing titles and empty
space around components.
To put a border around a JComponent
, you use its
setBorder
method. You can use the BorderFactory
class to create most of the borders that Swing provides. Here is an example of
code that creates a bordered container:
JPanel pane = new JPanel(); pane.setBorder(BorderFactory.createLineBorder(Color.black));
Here's a picture of the container, which contains a label component. The black line drawn by the border marks the edge of the container.
The following pictures show an application called
BorderDemo
that displays the borders Swing provides. We show the
code for creating these borders a little later, in Using
the Borders Provided by Swing.
The code that follows shows how to create and set the borders you
saw in the preceding figures. You can find the program's code in BorderDemo.java
. To run the
program, you will also need to put an image file in a directory named
images
: left.gif
.
As you probably noticed, the code uses the//Keep references to the next few borders, for use in titles //and compound borders. Border blackline, etched, raisedbevel, loweredbevel, empty; blackline = BorderFactory.createLineBorder(Color.black); etched = BorderFactory.createEtchedBorder(); raisedbevel = BorderFactory.createRaisedBevelBorder(); loweredbevel = BorderFactory.createLoweredBevelBorder(); empty = BorderFactory.createEmptyBorder(); //Simple borders jComp2.setBorder(blackline); jComp3.setBorder(raisedbevel); jComp4.setBorder(loweredbevel); jComp5.setBorder(empty); //Matte borders ImageIcon icon = new ImageIcon("images/left.gif"); //20x22 jComp6.setBorder(BorderFactory.createMatteBorder( -1, -1, -1, -1, icon)); jComp7.setBorder(BorderFactory.createMatteBorder( 1, 5, 1, 1, Color.red)); jComp8.setBorder(BorderFactory.createMatteBorder( 0, 20, 0, 0, icon)); //Titled borders TitledBorder title1, title2, title3, title4, title5; title1 = BorderFactory.createTitledBorder("title"); jComp9.setBorder(title1); title2 = BorderFactory.createTitledBorder( blackline, "title"); title2.setTitleJustification(TitledBorder.CENTER); jComp10.setBorder(title2); title3 = BorderFactory.createTitledBorder( etched, "title"); title3.setTitleJustification(TitledBorder.RIGHT); jComp11.setBorder(title3); title4 = BorderFactory.createTitledBorder( loweredbevel, "title"); title4.setTitlePosition(TitledBorder.ABOVE_TOP); jComp12.setBorder(title4); title5 = BorderFactory.createTitledBorder( empty, "title"); title5.setTitlePosition(TitledBorder.BOTTOM); jComp13.setBorder(title5); //Compound borders Border compound1, compound2, compound3; Border redline = BorderFactory.createLineBorder(Color.red); //This creates a nice frame. compound1 = BorderFactory.createCompoundBorder( raisedbevel, loweredbevel); jComp14.setBorder(compound1); //Add a red outline to the frame. compound2 = BorderFactory.createCompoundBorder( redline, compound1); jComp15.setBorder(compound2); //Add a title to the red-outlined frame. compound3 = BorderFactory.createTitledBorder( compound2, "title", TitledBorder.CENTER, TitledBorder.BELOW_BOTTOM); jComp16.setBorder(compound3);
BorderFactory
class to create each border. The
BorderFactory
class, which is in the javax.swing
package, returns objects that implement the Border
interface.
The Border
interface, as well as its Swing-provided
implementations, is in the javax.swing.border
package. You often don't need to directly use anything in the border package,
except when specifying constants that are specific to a particular border
class or when referring to the Border
type.
If BorderFactory
doesn't offer you enough control
over a border's form, then you might need to directly use the API in the
border package -- or even define your own border. In addition to containing
the Border
interface, the border package contains the classes
that implement the borders you've already seen: LineBorder
,
EtchedBorder
,
BevelBorder
,
EmptyBorder
,
MatteBorder
,
TitledBorder
,
and CompoundBorder
.
The border package also contains a class named SoftBevelBorder
,
which produces a result similar to BevelBorder
, but with softer
edges.
If none of the Swing borders is suitable, you can implement your own
border. Generally, you do this by creating a subclass of the AbstractBorder
class. In your subclass, you must implement at least one constructor and the
following two methods:
paintBorder
, which contains the drawing code that a
JComponent
executes to draw the border.
getBorderInsets
, which specifies the amount of space the
border needs to draw itself. isBorderOpaque
method so that it returns
true
. For examples of implementing borders, see the source code
for the classes in the javax.swing.border
package.
Many of the ready-to-use Swing components use borders to draw the outline of the component. If you want to draw an additional border around an already bordered component -- to provide some extra space above a scroll pane, for example -- then you need to add the new border to the existing border. Be sure to test the component to make sure that it works well with your extra border; components that change their border depending on their state probably aren't good candidates for additional borders. Here's an example of adding to an existing border:
aJComponent.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(20,0,0,0), aJComponent.getBorder()) );
The new border returned by createEmptyBorder
adds 20 pixels of
empty space above any component that uses it. The code uses the
createCompoundBorder
method to combine the new border with the
existing border, which is returned by getBorder
.
The following tables list the commonly used border methods. The API for using borders falls into two categories:
Method | Purpose |
---|---|
Border createLineBorder(Color) |
Create a line border. The first argument is a
java.awt.Color object that specifies the color of the line.
The optional second argument specifies the width in pixels of the
line. |
Border createEtchedBorder() |
Create an etched border. The optional arguments specify the highlight and shadow colors to be used. |
Border
createLoweredBevelBorder() |
Create a border that gives the illusion of the component being lower than the surrounding area. |
Border createRaisedBevelBorder() |
Create a border that gives the illusion of the component being higher than the surrounding area. |
Border createBevelBorder(int, Color, Color)
|
Create a raised or lowered beveled border, specifying the colors to
use. The integer argument can be either RAISED or
LOWERED (constants defined in BevelBorder ). With the
three-argument constructor, you specify the highlight and shadow colors,
With the five-argument constructor, you specify the outer highlight,
inner highlight, outer shadow, and inner shadow colors, in that
order. |
Border createEmptyBorder() |
Create an invisible border. If you specify no arguments, then the border takes no space, which is useful when creating a titled border with no visible boundary. The optional arguments specify the number of pixels that the border occupies at the top, left, bottom, and right (in that order) of whatever component uses it. |
MatteBorder createMatteBorder(int, int, int, int,
Color) |
Create a matte border. The integer arguments specify the number of pixels that the border occupies at the top, left, bottom, and right (in that order) of whatever component uses it. The Color argument specifies the color which with the border should fill its area. The Icon argument specifies the icon which with the border should tile its area. |
TitledBorder createTitledBorder(String)
|
Create a titled border. The string argument specifies the title to
be displayed. The optional font and color arguments specify the font and
color to be used for the title's text. The border argument specifies the
border that should be displayed along with the title. If no border is
specified, then a look-and-feel-specific default border is used.
By default, the title straddles the top of its companion border and
is left-justified. The optional integer arguments specify the title's
position and justification, in that order. |
CompoundBorder createCompoundBorder(Border,
Border) |
Combine two borders into one. The first argument specifies the outer border; the second, the inner border. |
Method | Purpose |
---|---|
void setBorder(Border) |
Set or get the border of the receiving
JComponent . |
void setBorderPainted(boolean) (in AbstractButton ,
JMenuBar , JPopupMenu ,
JProgressBar , and JToolBar ) |
Set or get whether the border of the component should be painted. |
import java.awt.*; import java.awt.event.*; import javax.swing.BorderFactory; import javax.swing.border.Border; import javax.swing.border.TitledBorder; import javax.swing.ImageIcon; import javax.swing.JTabbedPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JFrame; import javax.swing.Box; import javax.swing.BoxLayout; public class BorderDemo extends JFrame { public BorderDemo() { super("BorderDemo"); Border blackline, etched, raisedbevel, loweredbevel, empty; //A border that puts 10 extra pixels at the sides and //bottom of each pane. Border paneEdge = BorderFactory.createEmptyBorder(0,10,10,10); blackline = BorderFactory.createLineBorder(Color.black); etched = BorderFactory.createEtchedBorder(); raisedbevel = BorderFactory.createRaisedBevelBorder(); loweredbevel = BorderFactory.createLoweredBevelBorder(); empty = BorderFactory.createEmptyBorder(); //First pane: simple borders JPanel simpleBorders = new JPanel(); simpleBorders.setBorder(paneEdge); simpleBorders.setLayout(new BoxLayout(simpleBorders, BoxLayout.Y_AXIS)); addCompForBorder(blackline, "line border", simpleBorders); addCompForBorder(etched, "etched border", simpleBorders); addCompForBorder(raisedbevel, "raised bevel border", simpleBorders); addCompForBorder(loweredbevel, "lowered bevel border", simpleBorders); addCompForBorder(empty, "empty border", simpleBorders); //Second pane: matte borders JPanel matteBorders = new JPanel(); matteBorders.setBorder(paneEdge); matteBorders.setLayout(new BoxLayout(matteBorders, BoxLayout.Y_AXIS)); //XXX: We *should* size the component so that the //XXX: icons tile OK. Without that, the icons are //XXX: likely to be cut off and look bad. ImageIcon icon = new ImageIcon("left.gif"); //20x22 Border border = BorderFactory.createMatteBorder(-1, -1, -1, -1, icon); addCompForBorder(border, "matte border (-1,-1,-1,-1,icon)", matteBorders); border = BorderFactory.createMatteBorder(1, 5, 1, 1, Color.red); addCompForBorder(border, "matte border (1,5,1,1,Color.red)", matteBorders); border = BorderFactory.createMatteBorder(0, 20, 0, 0, icon); addCompForBorder(border, "matte border (0,20,0,0,icon)", matteBorders); //Third pane: titled borders JPanel titledBorders = new JPanel(); titledBorders.setBorder(paneEdge); titledBorders.setLayout(new BoxLayout(titledBorders, BoxLayout.Y_AXIS)); TitledBorder titled; titled = BorderFactory.createTitledBorder("title"); addCompForBorder(titled, "default titled border" + " (default just., default pos.)", titledBorders); titled = BorderFactory.createTitledBorder( blackline, "title"); addCompForTitledBorder(titled, "titled line border" + " (centered, default pos.)", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION, titledBorders); titled = BorderFactory.createTitledBorder(etched, "title"); addCompForTitledBorder(titled, "titled etched border" + " (right just., default pos.)", TitledBorder.RIGHT, TitledBorder.DEFAULT_POSITION, titledBorders); titled = BorderFactory.createTitledBorder( loweredbevel, "title"); addCompForTitledBorder(titled, "titled lowered bevel border" + " (default just., above top)", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.ABOVE_TOP, titledBorders); titled = BorderFactory.createTitledBorder( empty, "title"); addCompForTitledBorder(titled, "titled empty border" + " (default just., bottom)", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.BOTTOM, titledBorders); //Fourth pane: compound borders JPanel compoundBorders = new JPanel(); compoundBorders.setBorder(paneEdge); compoundBorders.setLayout(new BoxLayout(compoundBorders, BoxLayout.Y_AXIS)); Border redline = BorderFactory.createLineBorder(Color.red); Border compound; compound = BorderFactory.createCompoundBorder( raisedbevel, loweredbevel); addCompForBorder(compound, "compound border (two bevels)", compoundBorders); compound = BorderFactory.createCompoundBorder( redline, compound); addCompForBorder(compound, "compound border (add a red outline)", compoundBorders); titled = BorderFactory.createTitledBorder( compound, "title", TitledBorder.CENTER, TitledBorder.BELOW_BOTTOM); addCompForBorder(titled, "titled compound border" + " (centered, below bottom)", compoundBorders); JTabbedPane tabbedPane = new JTabbedPane(); tabbedPane.addTab("Simple", null, simpleBorders, null); tabbedPane.addTab("Matte", null, matteBorders, null); tabbedPane.addTab("Titled", null, titledBorders, null); tabbedPane.addTab("Compound", null, compoundBorders, null); tabbedPane.setSelectedIndex(0); getContentPane().add(tabbedPane, BorderLayout.CENTER); } void addCompForTitledBorder(TitledBorder border, String description, int justification, int position, Container container) { border.setTitleJustification(justification); border.setTitlePosition(position); addCompForBorder(border, description, container); } void addCompForBorder(Border border, String description, Container container) { JPanel comp = new JPanel(false); JLabel label = new JLabel(description, JLabel.CENTER); comp.setLayout(new GridLayout(1, 1)); comp.add(label); comp.setBorder(border); container.add(Box.createRigidArea(new Dimension(0, 10))); container.add(comp); } public static void main(String[] args) { JFrame frame = new BorderDemo(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } }