Previous | Next | Trail Map | Creating a User Interface | Using the JFC/Swing Packages

How to Use Scroll Panes

A JScrollPane(in the API reference documentation) provides a scrollable view of another Swing component. When screen real estate is limited, use a scroll pane to display a component that is large or one whose size can change dynamically.

The code to create a scroll pane can be minimal. For example, here's a picture of a demo program that uses a scroll pane to view textual output:
[PENDING: identify the scroll pane in the picture with an arrow]

And here's the code that creates the text area, puts it in the scroll pane, and adds the scroll pane to the window:
textArea = new JTextArea(5, 30);
JScrollPane scrollPane = new JScrollPane(textArea);
...
contentPane.setPreferredSize(new Dimension(400, 100));
...
contentPane.add(scrollPane, BorderLayout.CENTER);
Note that the code sample sets the preferred size on the window's content pane. If a scroll pane's size is unlimited by its preferred (or minimum?) size, or its container's preferred (or minimum?) size, then the scroll pane will be exactly large enough to contain the entire component to be scrolled, thereby making the scroll pane unnecessary.

If all you need to do is providing basic scrolling for a Swing component, read no further. As this demo program illustrates, a generic scroll pane is sufficient for many programs.

However, a scroll pane is a highly-customizable object: you can provide row and column headers, set the scroll bar policy for each scroll bar, and customize the corners. If you want to know more, you can read about the following topics in this section:

The Architecture of a Scroll Pane

The following figure shows the architecture of a scroll pane:

[PENDING: fix this picture so that it matches the description better]

The area drawn by a scrollpane is divided into nine parts each drawn and managed by a separate object: the center, four sides, and four corners. The center is the only component that is always present in all scroll panes. Each of the four sides is optional. When two intersecting sides are present, the corner where they intersect is also present. Here is a snapshot of an application that uses a fully-loaded scroll pane to view a picture of Mary's dad as a youth:
This scroll pane's client is a JLabel displaying a large image. The scroll pane uses both scrollbars, displays both row and column headers, and has three custom corners, one of which contains a toggle button.

Try this:
  1. Compile and run the application. The main source file is ScrollDemo.java. You will also need Rule.java, Corner.java and youngdad.jpeg.
    See Getting Started with Swing if you need help.
  2. Manipulate the view with the vertical and horizontal scrollbars. Watch the row and column headers scroll along.
  3. Click the in toggle in the upper left corner. The units on the row and column headers change to centimeters (or back to inches).

The remaining sections dissect various portions of the source code that create and set up the scroll pane in this program.

Setting Up the Scroll Bars

Here's the code from ScrollDemo.java that creates the scroll pane:
// Set up the picture label
ImageIcon david = new ImageIcon("images/youngdad.jpeg");
JLabel picture = new JLabel(david);

// Put it in a scroll pane
pictureScrollPane = new JScrollPane(picture,
			ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
			ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
);
pictureScrollPane.setPreferredSize(new Dimension(300, 250));
The scroll pane is created with the JScrollPane constructor that requires three arguments: the scrollable client, the vertical scrolling policy, and the horizontal scrolling policy. Note that the code snippet sets the preferred size of the scroll pane so that the scroll pane is smaller than the picture.

The scrollable client can be any Swing component. You can change a scroll pane's client dynamically with setViewportView. [PENDING: why doesn't the client have to be Scrollable? check on that and write about it].

Specify the vertical and horizontal scrolling policies with one of the following ints defined in the ScrollPaneConstants(in the API reference documentation) interface which is implemented by JScrollPane:

OrientationPolicyDescription
Vertical VERTICAL_SCROLLBAR_AS_NEEDED The default. The vertical scroll bar appears when the viewport is shorter than the scrollable client.
VERTICAL_SCROLLBAR_ALWAYS Always display the vertical scroll bar. The scroll bar knobs disappear if the viewport is tall enough to show the whole client.
VERTICAL_SCROLLBAR_NEVER Never display the vertical scroll bar. [PENDING: why use this option?]
Horizontal HORIZONTAL_SCROLLBAR_AS_NEEDED The default. The horizontal scroll bar appears when the viewport is narrower than the scrollable client.
HORIZONTAL_SCROLLBAR_ALWAYS Always display the horizontal scroll bar. The scroll bar knobs disappear if the viewport is wide enough to show the whole client.
HORIZONTAL_SCROLLBAR_NEVER Never display the horizontal scroll bar. [PENDING: why use this option?]

You can change a scroll pane's policies dynamically with the setHorizontalScrollBarPolicy and setVerticalScrollBarPolicy methods.

Providing Custom Decorations

The scroll pane in ScrollDemo.java uses both scrollbars, a row header, and a column header. Because all four sides are populated, all four corners are present--three of which are customized. The following figure shows the classes that participate in drawing the various areas of the scroll pane from ScrollDemo.java:

[PENDING: ... snapshot of ScrollDemo, with callouts]

The scroll pane's row and column headers are provided by a custom JComponent subclass, Rule.java, that draws a ruler in inches or centimeters. Here's the code that creates and sets the scroll pane's row and column headers:

...where the member variables are defined...
private Rule columnView;
private Rule rowView;
    ...
    columnView = new Rule(Rule.HORIZONTAL, false);
    columnView.setPreferredWidth(david.getIconWidth());
    pictureScrollPane.setColumnHeaderView(columnView);

    rowView = new Rule(Rule.VERTICAL, false);
    rowView.setPreferredHeight(david.getIconHeight());
    pictureScrollPane.setRowHeaderView(rowView);
    ...
You can use any Swing component for a scroll pane's row and column headers. The scroll pane puts the row and column headers in JViewPorts of their own. When scrolling horizontally, the column header follows along. When scrolling vertically, the row header follows along.

You can also use any Swing component for the corners of a scroll pane. ScrollDemo.java illustrates this by putting a toggle button in the upper left corner, and custom Corner objects in the upper right and lower left corners. Here's the code that creates the corner objects and calls setCorner to place them:

...create the toggle button...
isImperial = new JToggleButton("in", true);
isImperial.setMargin(new Insets(2,2,2,2));
isImperial.setAlignmentY(CENTER_ALIGNMENT);
isImperial.setAlignmentX(CENTER_ALIGNMENT);
isImperial.addItemListener(new UnitsListener());
JPanel corner = new JPanel();
corner.add(isImperial);

...set the corners...
pictureScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, corner);
pictureScrollPane.setCorner(JScrollPane.LOWER_LEFT_CORNER,
				new Corner());
pictureScrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER,
				new Corner());
Remember that the size of each corner is completely determined by the size of the sides intersecting there. You must take care that the object in the corner fits in its corner. The Corner class does this by drawing within its bounds which are set by the scroll pane. The toggle button was set up specifically to fit within the corner established by the headers.

As you can see from the code, constants indicate the corner positions. This diagram shows the constant for each position:

[PENDING: a little diagram]

The constants are defined in the ScrollPaneConstants interface.

About View Ports

[PENDING: Talk about the three viewports, draw pictures]

API Tables for Scrolling

[PENDING: Put tables here. potentially do something unorthodox and put tables for all classes and interfaces that participate in scrolling:JScrollPane, JViewPort, JScrollBar, Scrollable, ScrollPaneConstants]

Examples that Use JScrollPane

This table shows the examples that use JScrollPane and where those examples are described.

Example Where Described Notes
ToolBarDemo.java This page and
How to Use Tool Bars.
Shows a simple, yet typical, use of a scroll pane.
ScrollDemo.java This page. Uses many of scroll pane's bells and whistles.
ImageChooser.java How to Use Lists. Puts a list in a scroll pane. Also, shows how to handle the case when a scrollable client changes size.
TableDemo.java How to Use Tables Puts a table in a scroll pane.
TreeDemo.java How to Use Trees Puts a tree in a scroll pane.
EeyoreQuotes.java How to Use Text Components Puts a JEditorPane in a scroll pane.


Previous | Next | Trail Map | Creating a User Interface | Using the JFC/Swing Packages