| JPanel |
|---|
JPanel exactly the same
way as you would a Panel. Allocate it, drop components in
it, then add the JPanel to some
Container. However, JPanel also acts as a
replacement for Canvas (there is no
JCanvas). When using JPanel as a drawing
area in lieu of a Canvas, there are two additional steps
you usually need to follow. First, you should set the preferred size
via setPreferredSize (recall that a Canvas'
preferred size is just its current size, while a Panel
and JPanel determine their preferred size from the
components they contain). Secondly, you should use
paintComponent for drawing, not paint. And
since double-buffering is turned on by default, the first thing you
normally do in paintComponent is clear the off-screen
bitmap via super.paintComponent. E.g.:
public void paintComponent(Graphics g) {
super.paintComponent(g);
...
}
Note that if you are using Swing in Java 1.2, you can cast the
Graphics object to a Graphics2D object
and do all sorts of new stuff added in the Java2D package. This is a
whole topic in its own right: please see my
Java2D Tutorial.
JPanels. Swing gives you
seven basic border types: titled, etched, beveled (regular plus a
"softer" version), line, matte, compound, and empty. You can
also create your own, of course. You assign a Border via
the setBorder method, and create the Border
either by calling the constructors directly, or more often by using
one of the following convenience methods in
BorderFactory: createTitledBorder,
createEtchedBorder, createBevelBorder,
createRaisedBevelBorder,
createLoweredBevelBorder, createLineBorder,
createMatteBorder, createCompoundBorder, and
createEmptyBorder. These factory methods reuse existing
Border objects whenever possible.
As a convenience, JPanel lets you supply the
LayoutManager to the constructor in addition to
specifying it later via setLayout as with Panel.
LineBorder, while the other three use
TitledBorder.
import java.awt.*;
import javax.swing.*;
public class JPanels extends JFrame {
public static void main(String[] args) {
new JPanels();
}
public JPanels() {
super("Using JPanels with Borders");
WindowUtilities.setNativeLookAndFeel();
addWindowListener(new ExitListener());
Container content = getContentPane();
content.setBackground(Color.lightGray);
JPanel controlArea = new JPanel(new GridLayout(3, 1));
String[] colors = { "Red", "Green", "Blue",
"Black", "White", "Gray" };
controlArea.add(new SixChoicePanel("Color", colors));
String[] thicknesses = { "1", "2", "3", "4", "5", "6" };
controlArea.add(new SixChoicePanel("Line Thickness",
thicknesses));
String[] fontSizes = { "10", "12", "14", "18", "24", "36" };
controlArea.add(new SixChoicePanel("Font Size",
fontSizes));
content.add(controlArea, BorderLayout.EAST);
JPanel drawingArea = new JPanel();
// Preferred height is irrelevant, since using WEST region
drawingArea.setPreferredSize(new Dimension(400, 0));
drawingArea.setBorder(BorderFactory.createLineBorder (Color.blue, 2));
drawingArea.setBackground(Color.white);
content.add(drawingArea, BorderLayout.WEST);
pack();
setVisible(true);
}
}
Note: also requires
WindowUtilities.java
and ExitListener.java,
shown earlier.
import java.awt.*;
import javax.swing.*;
public class SixChoicePanel extends JPanel {
public SixChoicePanel(String title, String[] buttonLabels) {
super(new GridLayout(3, 2));
setBackground(Color.lightGray);
setBorder(BorderFactory.createTitledBorder(title));
ButtonGroup group = new ButtonGroup();
JRadioButton option;
int halfLength = buttonLabels.length/2; // Assumes even length
for(int i=0; i<halfLength; i++) {
option = new JRadioButton(buttonLabels[i]);
group.add(option);
add(option);
option = new JRadioButton(buttonLabels[i+halfLength]);
group.add(option);
add(option);
}
}
}