JPanel

1. JPanel Basics

In the simplest case, you use a 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.

2. New Features: Borders

Aside from double buffering, the most obvious new feature is the ability to assign borders to 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.

3. JPanel Example: Source Code

The following example allocates four bordered panels, set up to look like a simple drawing program. The large one at the left uses a LineBorder, while the other three use TitledBorder.

JPanels.java (Download source code)

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.

SixChoicePanel.java (Download source code)

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);
    }
  }
}

4. JPanel Example: Result

Using borders with JPanels


This page is part of my Quick Swing Tutorial for AWT Programmers. © 1999 Marty Hall. All source code freely available for unrestricted use. Created for for work in the Research and Technology Development Center of the Johns Hopkins University Applied Physics Lab, for courses in the Johns Hopkins Part-Time MS Program in Computer Science, and for various industry seminars and Java short courses.