Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 

Swing Chapter 7. (The basics) Scrolling Panes. Easy for reading, Click here!

Custom Search
Swing Chapter 7. (The basics) Scrolling Panes. Easy for reading, Click here!

[ Return to Swing (Book) ]

Page: 1/3 



Next Page (2/3) Next Page
Subpages: 1. JScrollPane
2. Grab-and-drag scrolling
3. Scrolling programmatically

Chapter 7. Scrolling Panes

In this chapter:

  •          JScrollPane
  •          Grab-and-drag scrolling
  •          Programmatic scrolling

7.1    JScrollPane

class javax.swing.JScrollPane

Using JScrollPane is normally very simple. Any component or container can be placed in a JScrollPane and scrolled. Simply create a JScrollPane by passing its constructor the component you'd like to scroll:

    JScrollPane jsp = new JScrollPane(myLabel);

Normally, our use of JScrollPane will not be much more extensive than the one line of code shown above. The following is a simple JScrollPane demo appliction. Figure 7.1 illustrates:

Figure 7.1 JScrollPane demo

<<file figure7-1.gif>>

The Code: ScrollPaneDemo.java

see \Chapter7\1

import java.awt.*;

import javax.swing.*;

public class ScrollPaneDemo extends JFrame

{

  public ScrollPaneDemo() {

    super("JScrollPane Demo");

    ImageIcon ii = new ImageIcon("earth.jpg");

    JScrollPane jsp = new JScrollPane(new JLabel(ii));

    getContentPane().add(jsp);

    setSize(300,250);

    setVisible(true);

  }

  public static void main(String[] args) {

    new ScrollPaneDemo();

  }

}

When you run this example try scrolling by pressing or holding down any of the scroll bar buttons. You will find this unacceptably slow because the scrolling occurs one pixel at a time. We will see how to control this shortly.

Many components use a JScrollPane internally to display their contents, such as JComboBox and JList. We are normally expected to place all multi-line text components inside scroll panes (although this is not default behavior).

UI Guideline : Using Scroll Panes

For many applications it is best to avoid the introduction of a scrollpane and concentrate on puting the required data on a screen such that scrolling is unnecessary. However, this is not always possible. When you do need to introduce scrolling put some thought into the type of data and application. If possible try to introduce scrolling in only 1 direction. For example, with text documents, western culture has been used to scrolling vertically since Egyptian times. Usability studies for World Wide Web pages have shown that readers can find data quickly when vertically scrolling. Scrolling horizontally, however, is labourious and difficult with text. Try to avoid it. With visual information, e.g. tables of information, it may be more appropriate for horizontal scrolling, but try to avoid horizontal and vertical scrolling if possible.

We can access a JScrollPane's scroll bars directly with its getXXScrollBar() and setXXScrollBar() methods, where XX is either HORIZONTAL or VERTICAL.

Reference: In chapter 13 we'll talk more about JScrollBars

7.1.1    Scrollbar policies

abstract interface javax.swing.ScrollPaneConstants

We can specify specific policies for when and when not to display a JScrollPane's horizontal and vertical scrollbars.  We simply use its setVerticalScrollBarPolicy() and setHorizontalScrollBarPolicy() methods, provding one of three constants defined in the ScrollPaneConstants interface:

    HORIZONTAL_SCROLLBAR_AS_NEEDED

    HORIZONTAL_SCROLLBAR_NEVER

    HORIZONTAL_SCROLLBAR_ALWAYS

    VERTICAL_SCROLLBAR_AS_NEEDED

    VERTICAL_SCROLLBAR_NEVER

    VERTICAL_SCROLLBAR_ALWAYS

For example, to enforce the display of the vertical scrollbar at all times and always keep the horizontal scrollbar hidden, we could do the following:

    jsp.setHorizontalScrollBarPolicy(

      ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

    jsp.setVerticalScrollBarPolicy(

      ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

7.1.2    JViewport

class javax.swing.JViewport

The JViewport class is the container that is really responsible for displaying a specific visible region of the component in JScrollPane. We can set/get a viewport's view (the component it contains) using its setView() and getView() methods. We can control how much of this component JViewport displays by setting its extent size to a specified Dimension using its setExtentSize() method. We can also specify where the origin (upper left corner) of a JViewport should begin displaying its contained component by providing specific coordinates (as a Point) of the contained component to the setViewPosition() method. In fact, when we scroll a component in a JScrollPane this view position is constantly being changed by the scrollbars.

Note: JViewport enforces a view position that lies within the view component only. We cannot set negative or extremely large view positions (as of JDK1.2.2 we can set negative view positions). However, since the view position is the upper right hand corner of the viewport, we are still allowed to set the view position such that only part of the viewport is filled. We will show how to watch for this, and stop it from happening, in some of the examples below.

Whenever a change is made to the position or size of the visible portion of the view, JViewport fires ChangeEvents. We can register ChangeListeners to capture these events using JViewport's addChangeListener() method. These are the only events that are associated with JScrollPane by default. For instance, whenever we scroll using JScrollPane's scroll bars, its main viewport, as well as its row and column header viewports (see below), will each fire ChangeEvents.

The visible region of JViewport's view can be retrieved as a Rectangle or Dimension instance using the getViewRect() and getViewSize() methods respectively. This will give us the current view position as well as the extent width and hieght. The view position alone can be retrieved with getViewPosition(), which returns a Point instance. To remove a component from JViewport we use its remove() method.

We can translate specific JViewport coordinates to the coordinates of its contained component by passing a Point instance to its toViewCoordinates() method. We can do the same for a region by passing toViewCoordinates() a Dimension instance. We can also manually specify the visible region of the view component by passing a Dimension instance to JViewport's scrollRectToVisible() method.

We can retreive JScrollPane's main JViewport by calling its getViewport() method, or assign it a new one using setViewport(). We can replace the component in this viewport through JScrollPane's setViewportView() method, but there is no getViewportView() counterpart. Instead we must first access its JScrollPane's JViewport by calling getViewport(), and then call getView() on that (as discussed above). Typically, to access a JScrollPane's main child component we would do the following:

    Component myComponent = jsp.getViewport().getView();

7.1.3    ScrollPaneLayout

class javax.swing.ScrollPaneLayout

By default JScrollPane's layout is managed by an instance of ScrollPaneLayout. JScrollPane can contain up to nine components and it is ScrollPaneLayout's job to make sure that they are positioned correctly. These components are:

A JViewport containing the main component to be scrolled.

A JViewport used as the row header. This viewport's view position changes vertically in sync with the main viewport.

A JViewport used as the column header. This viewport's view position changes horizontally in sync with the main viewport.

Four components for placement in each corner of the scroll pane.

Two JScrollBars for vertical and horizontal scrolling.

The corner components will only be visible if the scrollbars and headers surrounding them are also visible. To assign a component to a corner position we can call JScrollPane's setCorner() method. This method takes both a String and a component as parameters. The String is used to identify which corner this component is to be placed in, and is recognized by ScrollPaneLayout. In fact ScrollPaneLayout identifies each JScrollPane component with a unique String. Figure 7.2 illustrates:

Figure 7.2 JScrollPane components as identified by ScrollPaneLayout

<<file figure7-2.gif>>

To assign JViewports as the row and column headers we use JScrollPane's setRowHeader() and setColumnHeader() methods respectively. We can also avoid the creation of a JViewport ourselves by passing the component to be placed in the row or column viewport to JScrollPane's setRowHeaderView() or setColumnHeaderView() methods.

Because JScrollPane is most often used to scroll images, the most obvious use for the row and column headers is to function as some sort of ruler. Here we present a basic example showing how to populate each corner with a label and create some simple rulers for the row and column headers that display ticks every 30 pixels, and render themselves based on their current viewport position. Figure 7.3 illustrates:

Figure 7.3 JScrollPane demo with 4 corners, row header, and column header.

<<file figure7-3.gif>>

The Code: HeaderDemo.java

see \Chapter7\2

import java.awt.*;

import javax.swing.*;

public class HeaderDemo extends JFrame

{

  public HeaderDemo() {

    super("JScrollPane Demo");

    ImageIcon ii = new ImageIcon("earth.jpg");

    JScrollPane jsp = new JScrollPane(new JLabel(ii));

    JLabel[] corners = new JLabel[4];

    for(int i=0;i<4;i++) {

      corners[i] = new JLabel();

      corners[i].setBackground(Color.yellow);

      corners[i].setOpaque(true);

      corners[i].setBorder(BorderFactory.createCompoundBorder(

        BorderFactory.createEmptyBorder(2,2,2,2),

        BorderFactory.createLineBorder(Color.red, 1)));

    }

    JLabel rowheader = new JLabel() {

      Font f = new Font("Serif",Font.ITALIC | Font.BOLD,10);

      public void paintComponent(Graphics g) {

        super.paintComponent(g);

        Rectangle r = g.getClipBounds();

        g.setFont(f);

        g.setColor(Color.red);

        for (int i = 30-(r.y % 30);i<r.height;i+=30) {

          g.drawLine(0, r.y + i, 3, r.y + i);

          g.drawString("" + (r.y + i), 6, r.y + i + 3);

        }

      }

      public Dimension getPreferredSize() {

        return new Dimension(

         25, (int)label.getPreferredSize().getHeight());

      }

    };

    rowheader.setBackground(Color.yellow);

    rowheader.setOpaque(true);

    JLabel columnheader = new JLabel() {

      Font f = new Font("Serif",Font.ITALIC | Font.BOLD,10);

      public void paintComponent(Graphics g) {

        super.paintComponent(g);

        Rectangle r = g.getClipBounds();

        g.setFont(f);

        g.setColor(Color.red);

        for (int i = 30-(r.x % 30);i<r.width;i+=30) {

          g.drawLine(r.x + i, 0, r.x + i, 3);

          g.drawString("" + (r.x + i), r.x + i - 10, 16);

        }

      }

      public Dimension getPreferredSize() {

        return new Dimension(

         (int)label.getPreferredSize().getWidth(),25);

      }

    };

    columnheader.setBackground(Color.yellow);

    columnheader.setOpaque(true);

    jsp.setRowHeaderView(rowheader);

    jsp.setColumnHeaderView(columnheader);

    jsp.setCorner(JScrollPane.LOWER_LEFT_CORNER, corners[0]);

    jsp.setCorner(JScrollPane.LOWER_RIGHT_CORNER, corners[1]);

    jsp.setCorner(JScrollPane.UPPER_LEFT_CORNER, corners[2]);

    jsp.setCorner(JScrollPane.UPPER_RIGHT_CORNER, corners[3]);

    getContentPane().add(jsp);

    setSize(400,300);

    setVisible(true);

  }

  public static void main(String[] args) {

    new HeaderDemo();

  }

}

Notice that the row and column headers use the graphics clipping area in their paintComponent() routine for optimal efficiency. We also override the getPreferredSize() method so that the proper width (for the row header) and height (for the column header) will be used by ScrollPaneLayout. The other dimensions are obtained by simply grabbing the label's preferred size, as they are completely controlled by ScrollPaneLayout.

We are certainly not limited to labels for corners and row headers or within the main viewport itself. As we mentioned in the beginning of this chapter, any comoponent can be placed in a JViewport and scrolled in a JScrollPane.

7.1.4.   The Scrollable interface

The Scrollable interface describes five methods that allow us to customize how JScrollPane scrolls its contents. Specifically, by implementing this interface we can specify how many pixels are scrolled when a scroll bar button or scroll bar paging area (the empty region between the scroll bar thumb and the buttons) is pressed. There are two methods that control this functionality: getScrollableBlockIncrement() and getScrollableUnitIncrement(). The former is used to return the amount to scroll when a scroll bar paging area is pressed, the latter is used when the button is pressed.

Reference: In text components, these two methods are implemented so that scrolling will move one line of text at a time. (JTextComponent implements the Scrollable interface.)

The other three methods of this interface involve JScrollPane's communication with the main viewport. The getScrollableTracksViewportWidth() and getScrollableTracksHeight() methods can return true to disable scrolling in the horizontal or vertical direction respecively. Normally these just return false. The getPreferredSize() method is supposed to return the preferred size of the viewport that will contain this component (the component implementing the Scrollable interface). Normally we just return the preferred size of the component for this.

The following code shows how to implement the Scrollable interface to create a custom JLabel whose unit and block increments will be 10 pixels. As we saw in the example in the beginning of this chapter, scrolling one pixel at a time is tedious at best. Increasing this to a 10 pixel increment provides a more natural feel.

The Code: ScrollableDemo.java

see \Chapter7\3

import java.awt.*;

import javax.swing.*;

public class ScrollableDemo extends JFrame

{

  public ScrollableDemo() {

    super("JScrollPane Demo");

    ImageIcon ii = new ImageIcon("earth.jpg");

    JScrollPane jsp = new JScrollPane(new MyScrollableLabel(ii));

    getContentPane().add(jsp);

    setSize(300,250);

    setVisible(true);

  }

  public static void main(String[] args) {

    new ScrollableDemo();

  }

}

class MyScrollableLabel extends JLabel implements Scrollable

{

  public MyScrollableLabel(ImageIcon i){

    super(i);

  }

  public Dimension getPreferredScrollableViewportSize() {

    return getPreferredSize();

  }

  public int getScrollableBlockIncrement(Rectangle r,

    int orietation, int direction) {

      return 10;

  }

  public boolean getScrollableTracksViewportHeight() {

    return false;

  }

  public boolean getScrollableTracksViewportWidth() {

    return false;

  }

  public int getScrollableUnitIncrement(Rectangle r,

    int orientation, int direction) {

      return 10;

  }

}



[ Return to Swing (Book) ]


Top 10 read Java Articles
 Get free "1000 Java Tips eBook"

 Java Calendar and Date: good to know facts and code examples

 Array vs ArrayList vs LinkedList vs Vector: an excellent overview and examples

 How can I convert any Java Object into byte array? And byte array to file object

 The Java Lesson 1: What is Java?

 How do I compare two dates and times, date between dates, time between times and

 Maven vs Ant or Ant vs Maven?

 How to open, read, write, close file(s) in Java? Examples on move, rename and de

 Java Array

 Java: JLabel font and color


[ More in News Section ]
Java Lessons

The Java Lesson 1:
What is Java?
The Java Lesson 2:
Anatomy of a simple Java program
The Java Lesson 3:
Identifiers and primitive data types
The Java Lesson 4:
Variables, constants, and literals
The Java Lesson 5:
Arithmetic operations, conversions, and casts
The Java Lesson 6:
Boolean expressions and operations
The Java Lesson 7:
Bitwise operations
The Java Lesson 8:
Flow control with if and else
The Java Lesson 9:
switch statements
The Java Lesson 10:
for, while, and do-while statements
The Java Lesson 11:
Using break and continue
The Java Lesson 12:
Class methods and how they are called
The Java Lesson 13:
Using the Math class
The Java Lesson 14:
Creating and calling custom class methods
The Java Lesson 15:
Overloading class methods
The Java Lesson 16:
An introduction to objects and object references
The Java Lesson 17:
The String class
The Java Lesson 18:
The StringBuffer class
The Java Lesson 19:
Initializing and processing arrays of primitives
The Java Lesson 20:
Initializing and processing arrays of objects
The Java Lesson 23:
Inheritance and overriding inherited methods
The Java Lesson 24:
abstract classes and polymorphism
The Java Lesson 25:
Interfaces, instanceof, and object conversion and casting
The Java Lesson 26:
Introduction to graphical programming and the java.awt packa
The Java Lesson 27:
The Component class
The Java Lesson 28:
Containers and simple layout managers
The Java Lesson 29:
The Color and Font classes
The Java Lesson 30:
Drawing geometric shapes
The Java Lesson 31:
Choice, List, and Checkbox controls
The Java Lesson 32:
Using the Scrollbar graphical control
The Java Lesson 33:
Menus and submenus
The Java Lesson 34:
An introduction to applets and the Applet class
The Java Lesson 35:
Essential HTML to launch an applet and pass it parameters
The Java Lesson 36:
Mouse event processing
Java Lesson 37:
Menus and submenus
Java Lesson 38:
The WindowListener interface and the WindowAdapter class
Java Lesson 39:
An introduction to GridBagLayout
Java Lesson 40:
An introduction to the Java Collections API
Java Lesson 41:
Exception handling with try, catch, and finally blocks
Java Lesson 42:
Claiming and throwing exceptions
Java Lesson 43:
Multithreading, the Thread class, and the Runnable interface
Java Lesson 44:
An introduction to I/O and the File and FileDialog classes
Java Lesson 45:
Low-level and high-level stream classes
Java Lesson 46:
Using the RandomAccessFile class
Java Lessons by
Joh Huhtala: Update

Latest articles
 Java Profiler JProbe to Resolve Performance Problems Faster

 SSL with GlassFish v2, page 5

 SSL with GlassFish v2, page 4

 SSL with GlassFish v2, page 3

 SSL with GlassFish v2, page 2

 The Java Lesson 2: Anatomy of a simple Java program, page 2

 New site about Java for robots and robotics: both software and hardware.

 Exceptions -III: What's an exception and why do I care?

 Exceptions -II: What's an exception and why do I care?

 Exceptions: What's an exception and why do I care?

 Double your Java code quality in 10 minutes, here is receipt

 Murach's Java Servlets and JSP

 How to get ascii code from a char in Java?

 Can we just try without catch? Yes!

 Make Tomcat page load faster

 Make your Tomcat More secure - limit network address for certain IP addresses

 New Java book online starts now here...

 Implementing RESTful Web Services in Java

 Firefox trimming from 1 GB to 40 Mb with many tabs opened

 SSL with GlassFish v2

 My request to replublish Tech Tips

 Search JavaFAQ.nu site here

 New Advanced Installer for Java 6.0 brings XML updates and imports 3rd party MSI

 EJB programming restrictions

 Maven vs Ant or Ant vs Maven?

 Why Java does not use default value which it should?

 How to unsign signed bytes in Java - your guide is here

 The Java Lesson 3: Identifiers and primitive data types. Page 2

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 4

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 3


[ More in News Section ]


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy