Oct. 15, 2010, 11:59 p.m.
posted by pythonrocks
How to Use SlidersUse a JSlider[133] to let the user easily enter a numeric value bounded by a minimum and maximum value. If the ability to specify precise numbers is important, a slider can be coupled with a formatted text field. If space is limited, a spinner is a possible alternative to a slider.
Try This:
The following code from SliderDemo.java creates the slider in Figure.
static final int FPS_MIN = 0;
static final int FPS_MAX = 30;
static final int FPS_INIT = 15; //initial frames per second
. . .
JSlider framesPerSecond = new JSlider(JSlider.HORIZONTAL,
FPS_MIN, FPS_MAX, FPS_INIT);
framesPerSecond.addChangeListener(this);
//Turn on labels at major tick marks.
framesPerSecond.setMajorTickSpacing(10);
framesPerSecond.setMinorTickSpacing(1);
framesPerSecond.setPaintTicks(true);
framesPerSecond.setPaintLabels(true);
A picture of an application that uses a slider to control animation speed.
By default, spacing for major and minor tick marks is zero. To see tick marks, you must explicitly set the spacing for either major or minor tick marks (or both) to a nonzero value and call setPaintTicks(true). Just calling setPaintTicks(true) is not enough. To display standard, numeric labels at major tick mark locations, set the major tick spacing, then call setPaintLabels(true). The example program provides labels for its slider this way. But you don't have to settle for these labels. The next section, Customizing Labels on a Slider, shows you how to customize slider labels. When you move the slider's knob, the stateChanged method of the slider's ChangeListener is called. For information about change listeners, refer to How to Write a Change Listener (page 652). Here's the change listener code that reacts to slider value changes:
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusting()) {
int fps = (int)source.getValue();
if (fps == 0) {
if (!frozen) stopAnimation();
} else {
delay = 1000 / fps;
timer.setDelay(delay);
timer.setInitialDelay(delay * 10);
if (frozen) startAnimation();
}
}
}
Notice that our stateChanged method changes the animation speed only if getValueIs-Adjusting returns false. Many change events are fired as the user moves the slider knob. This program is interested only in the final result of the user's action. Customizing Labels on a SliderFigure shows a modified version of the previous program that uses a slider with custom labels. Figure. The SliderDemo2 example, which uses three custom labels: Fast, Slow, and Stop.
//Create the slider
JSlider framesPerSecond = new JSlider(JSlider.VERTICAL,
FPS_MIN, FPS_MAX, FPS_INIT);
framesPerSecond.addChangeListener(this);
framesPerSecond.setMajorTickSpacing(10);
framesPerSecond.setPaintTicks(true);
//Create the label table
Hashtable labelTable = new Hashtable();
labelTable.put( new Integer( 0 ), new JLabel("Stop") );
labelTable.put( new Integer( FPS_MAX/10 ), new JLabel("Slow") );
labelTable.put( new Integer( FPS_MAX ), new JLabel("Fast") );
framesPerSecond.setLabelTable( labelTable );
framesPerSecond.setPaintLabels(true);
Each key-value pair in the hashtable specified with setLabelTable gives the position and the value of one label. The hashtable key must be an Integer and a value within the slider's range at which to place the label. The hashtable value associated with each key must be a Component. This program uses JLabel instances with text only. An interesting variation would be to use JLabel instances with icons, or perhaps buttons that move the knob to the label's position. If you want a set of numeric labels positioned at a specific interval, you can use JSlider's createStandardLabels method to create the Hashtable for you. You can also modify the table returned by createStandardLabels to then customize it. Using a Formatted Text Field with a Slider
Figure. A screenshot of SliderDemo3, which uses a formatted text field that lets the user enter the number of frames per second.
The next few code snippets show the code in SliderDemo3.java that supports the formatted text field. If you find it hard to understand, you might want to refer to How to Use Formatted Text Fields (page 221). The following snippet creates the text field and its formatter. The formatter is created using an integer NumberFormat, and the number formatter's minimum and maximum are set to the same values used for the slider.
JFormattedTextField textField;
...
//Where the components are created:
java.text.NumberFormat numberFormat =
java.text.NumberFormat.getIntegerInstance();
NumberFormatter formatter = new NumberFormatter(numberFormat);
formatter.setMinimum(new Integer(FPS_MIN));
formatter.setMaximum(new Integer(FPS_MAX));
textField = new JFormattedTextField(formatter);
textField.setValue(new Integer(FPS_INIT));
textField.setColumns(5); //get some space
The rest of the code we'll show you sets up the event handling for the text field. But first you need to know that changing a formatted text field's text property (which always holds data of type String) doesn't directly change the formatted text field's value property (which, in this example, is a Number). The value property is set only after a method called commitEdit is invoked on the text field, which typically happens when the text field contains valid text and either the user presses Enter or the text field loses focus. The following code creates a key binding for the Enter key so that whenever the user puts valid text in the text field and presses Enter, the text field's value (a Number) is set accordingly. (If the text is invalid, the system beeps and selects all the text.) The key binding is created by adding entries to the text field's input and action maps. More information on input and action maps is in How to Use Key Bindings (page 623).
textField.getInputMap().put(KeyStroke.getKeyStroke(
KeyEvent.VK_ENTER, 0),
"check");
textField.getActionMap().put("check", anAction);
...
//Where anAction is implemented (as a subclass of AbstractAction):
public void actionPerformed(ActionEvent e) {
if (!textField.isEditValid()) { //The text is invalid.
Toolkit.getDefaultToolkit().beep();
textField.selectAll();
} else try { //The text is valid,
textField.commitEdit(); //so use it.
} catch (java.text.ParseException exc) { }
}
The next snippet shows how we make the slider's value change whenever the text field's value changes. Recall that framesPerSecond is the variable that refers to the JSlider.
textField.addPropertyChangeListener(this);
...
public void propertyChange(PropertyChangeEvent e) {
if ("value".equals(e.getPropertyName())) {
Number value = (Number)e.getNewValue();
if (framesPerSecond != null && value != null) {
framesPerSecond.setValue(value.intValue());
}
}
}
Finally, adding bit of code to the slider's change listener updates the formatted text field whenever the slider's value changes. While the user is dragging the slider, we update the text field's text—not its value—to prevent the text field's property-change listener from trying to update the slider (which might then try to update the text field, which would try to update the slider, and so on, in an unnecessary and perhaps unending cycle). Once the user has finished dragging the slider, we update the text field's value.
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider)e.getSource();
int fps = (int)source.getValue();
if (!source.getValueIsAdjusting()) { //done adjusting
textField.setValue(new Integer(fps)); //update ftf value
...
} else { //value is adjusting; just set the text
textField.setText(String.valueOf(fps));
}
}
You have seen one possible way of implementing a text field tied to a slider. Other ways are possible, but keep the following rules in mind:
For more information, see How to Use Formatted Text Fields (page 221). The Slider APIFigure through 75 list the commonly used JSlider constructors and methods. See The JComponent Class (page 53) for tables of commonly used inherited methods. Also refer to the JSlider API documentation at: http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JSlider.html.
Examples That Use SlidersThis table shows examples that use JSlider and where those examples are described.
|
- Comment


