 | Level: Introductory John Zukowski (jaz@zukowski.net), President, JZ Ventures, Inc.
01 Jul 2001 Welcome to Magic with Merlin, a bi-weekly series designed to give you a leg up on programming with Java 2 Standard Edition, version 1.4. Over the coming months, author John Zukowski will offer tips and tricks for navigating the wealth of new features in this release. In this installment, John describes the new JSpinner component of Swing, which allows you to choose dates, numbers, and selections from pick lists. The most recent release of the Java 2 SDK, the 1.4 beta, adds two powerful new components to the JFC/Swing component set. One of them, JSpinner, allows a user to easily select a date, number, or choice from a pick list. (The other is JFormattedTextField for formatted input support.)
Getting started
JSpinner lets you create an ordered list of values, which it displays one at a time in a selection box, as shown in Figure 1. Users click the up and down arrows to make selections. Figure 1. Sample JSpinner

Users make a selection by using the up and down arrows on the component or on the keyboard. They can also type in their choice. Unlike a JComboBox, however, JSpinner does not provide a drop-down list of selections so the choices and their order should make sense. To use the class, simply create a collection of elements to choose from (in either a List or array), create a SpinnerModel from the list, and create a JSpinner for the model: Listing 1. Simple JSpinner Usage
String[] months = new DateFormatSymbols().getMonths();
SpinnerModel model = new SpinnerListModel(months);
JSpinner spinner = new JSpinner(model);
|
There are several helper classes for creating the data model for the component, depending on the type of input you're after:
-
SpinnerDateModel: Used for accepting date input. This class supports changing the date by different settings via constants in the Calendar class; for example, Calendar.WEEK_OF_MONTH to change the date one week at a time.
-
SpinnerListModel: Used for accepting input from a list of values.
-
SpinnerNumberModel: Used for accepting input from a range of numbers (int or double) with a set step size.
Each of the SpinnerModel implementations relies on an editor for the input of the value. The editor must be a JComponent; the system-defined editors subclass JSpinner.DefaultEditor. One is available for each of the models:
-
JSpinner.DateEditor: For the SpinnerDateModel. Allows you to customize the input date format.
-
JSpinner.ListEditor: For the SpinnerListModel. Supports type-ahead to locate a value.
-
JSpinner.NumberEditor: For the SpinnerNumberModel. Allows you to customize the decimal format pattern.
The relationships between all these classes (and a few more) are shown in Figure 2. Figure 2. JSpinner UML relationship diagram

Event handling
The JSpinner component works like the other Swing components. If you're interested in finding out when the user changes the selection, you attach a listener. In the case of the JSpinner, that listener is a ChangeListener, which you can attach directly to the JSpinner or its SpinnerModel. While you can attach the listener to either, the source of the ChangeEvent when the value change happens is always the SpinnerModel: Listing 2. JSpinner event listening
ChangeListener listener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
SpinnerModel source = (SpinnerModel)e.getSource();
System.out.println("The value is: " + source.getValue());
}
};
model.addChangeListener(listener);
|
A complete example
Let's take a look at an example that uses all three of the different spinner models (Listing 3). The list model uses the set of month names, taken from the DateFormatSymbols class. The date model example changes the input format for the editor. (There seems to be a bug in the beta release that doesn't reformat the field when the editor changes.) It also moves the date a week at a time when using the arrows next to the field. The number model example lets the user pick a number from 0 to 100, jumping five at a time when using the arrows. Notice that the user can type in any number, not just those that are multiples of five. For all the components, the same change listener is attached to display when each spinner value actually changes. If you use the cursor keys to change the month, day, or year, you'll notice the value doesn't change until you hit the Enter key. Listing 3. JSpinner complete example
import javax.swing.*;
import javax.swing.event.*;
import java.text.*;
import java.awt.*;
import java.util.*;
public class Spinner {
public static void main (String args[]) throws Exception {
JFrame frame = new JFrame("Spinner");
frame.setDefaultCloseOperation(3);
String[] months = new DateFormatSymbols().getMonths();
SpinnerModel model = new SpinnerListModel(months);
JSpinner spinner = new JSpinner(model);
frame.getContentPane().add(spinner, BorderLayout.NORTH);
SpinnerDateModel model2 = new SpinnerDateModel();
model2.setCalendarField(Calendar.WEEK_OF_MONTH);
JSpinner spinner2 = new JSpinner(model2);
JSpinner.DateEditor editor2 = new JSpinner.DateEditor(
spinner2, "MMMMM dd, yyyy");
spinner2.setEditor(editor2);
frame.getContentPane().add(spinner2, BorderLayout.SOUTH);
SpinnerNumberModel model3 = new SpinnerNumberModel(50, 0, 100, 5);
JSpinner spinner3 = new JSpinner(model3);
frame.getContentPane().add(spinner3, BorderLayout.CENTER);
ChangeListener listener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
SpinnerModel source = (SpinnerModel)e.getSource();
System.out.println("The value is: " + source.getValue());
}
};
model.addChangeListener(listener);
model2.addChangeListener(listener);
model3.addChangeListener(listener);
frame.pack();
frame.show();
}
}
|
 |
Download | Description | Name | Size | Download method |
|---|
| Sample code | spinner.zip | 1 KB | HTTP |
|---|
Resources
About the author
Rate this page
|  |