I l@ve RuBoard |
![]() ![]() |
6.1 The Bounded-Range ModelComponents that use the bounded-range model typically consist of an integer value that is constrained within two integer boundaries. The lower boundary, the minimum , should always be less than or equal to the model's current value. In addition, the model's value should always be less than the upper boundary, the maximum. The model's value can cover more than one unit; this size is referred to as its extent. With bounded range, the user is allowed to adjust the value of the model according to the rules of the component. If the value violates any of the rules, the model can adjust the values accordingly. The javax.swing.BoundedRangeModel interface outlines the data model for such an object. Objects implementing the BoundedRangeModel interface must contain an adjustable integer value, an extent, a minimum, and a maximum. Swing contains three bounded-range components: JScrollBar, JSlider, and JProgressBar. These components are shown in Figure 6-1. Figure 6-1. Bounded-range components in Swing![]() 6.1.1 PropertiesTable 6-1 shows the properties of the BoundedRangeModel interface.
The minimum , maximum, and value properties form the actual bounded range. The extent property can give the value its own subrange. Extents can be used in situations where the model's value exceeds a single unit; they can also be changed dynamically. For example, the sliding "thumbs" of many scrollbars resize themselves based on the percentage of total information displayed in the window. If you wish to emulate this behavior with Swing, you could declare a bounded-range scrollbar and set the extent property to grow or shrink as necessary. Figure 6-2 illustrates a bounded range with the following properties: minimum = 1; maximum = 24; value = 9; extent = 3 Figure 6-2. Properties of the BoundedRangeModel interface![]() Extents always define a range greater than the model's value, never less. If you do not want the value to have a subrange, you can set the extent to 0. Here are some rules to remember when working with bounded ranges:
Finally, the valueIsAdjusting property is a boolean that indicates that the model is undergoing changes. JSlider, for example, toggles this property to true while the user is dragging the thumb. This alerts any ChangeEvent listeners on the component that this event is probably one in a series, and they may choose not to react immediately. 6.1.2 EventsObjects implementing the BoundedRangeModel interface must fire a ChangeEvent when the model modifies its minimum, maximum, value, or extent properties. The BoundedRangeModel interface contains the standard methods for maintaining a list of ChangeEvent subscribers.
6.1.3 Method
6.1.4 The DefaultBoundedRangeModel ClassSwing provides a standard implementation of the BoundedRangeModel interface with the DefaultBoundedRangeModel class. This class provides the minimum functionality necessary to correctly implement the bounded-range model. Programmers are free to use and extend this class as they see fit. 6.1.4.1 PropertiesThe properties of the DefaultBoundedRangeModel class are identical to the properties of the interface it implements; it provides default values but doesn't otherwise add or change properties, as shown in Table 6-2. See the BoundedRangeModel interface earlier in this chapter for a description of the rules this component follows when the values of its properties are changed.
6.1.4.2 EventsAs specified by the bounded-range interface, the DefaultBoundedRangeModel fires a ChangeEvent when the model modifies its minimum, maximum, value, or extent properties.
6.1.4.3 Constructors
6.1.4.4 Working with the bounded-range modelHere is a program that helps to demonstrate some of the features of the DefaultBoundedRangeModel class and the bounded-range interface. We intentionally try to confuse the model to show how it reacts to inappropriate property values. // Bounded.java // import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; public class Bounded { public Bounded( ) { try { DefaultBoundedRangeModel model = new DefaultBoundedRangeModel( ); ChangeListener myListener = new MyChangeListener( ); model.addChangeListener(myListener); System.out.println(model.toString( )); System.out.println("Now setting minimum to 50 . . . "); model.setMinimum(50); System.out.println(model.toString( )); System.out.println("Now setting maximum to 40 . . . "); model.setMaximum(40); System.out.println(model.toString( )); System.out.println("Now setting maximum to 50 . . . "); model.setMaximum(50); System.out.println(model.toString( )); System.out.println("Now setting extent to 30 . . . "); model.setExtent(30); System.out.println(model.toString( )); System.out.println("Now setting several properties . . . "); if (!model.getValueIsAdjusting( )) { model.setValueIsAdjusting(true); System.out.println(model.toString( )); model.setMinimum(0); model.setMaximum(100); model.setExtent(20); model.setValueIsAdjusting(false); } System.out.println(model.toString( )); } catch (Exception e) { e.printStackTrace( ); } } class MyChangeListener implements ChangeListener { public void stateChanged(ChangeEvent e) { System.out.println("A ChangeEvent has been fired!"); } } public static void main(String args[]) { new Bounded( ); } } Let's go through the output step by step. The first step is to define a DefaultBoundedRangeModel and attach a ChangeListener to it. After doing so, we print the default values of the model: DefaultBoundedRangeModel[value=0, extent=0, min=0, max=100, adj=false] Here, we set the minimum to 50 and the maximum to a value smaller than the minimum, 40. Looks like trouble ahead... Now setting minimum to 50 . . . A ChangeEvent has been fired! DefaultBoundedRangeModel[value=50, extent=0, min=50, max=100, adj=false] Now setting maximum to 40 (smaller than min) . . . A ChangeEvent has been fired! DefaultBoundedRangeModel[value=40, extent=0, min=40, max=40, adj=false] There are two things to note here. First, by resetting the minimum to 50, we let the value property fall outside the bounded range. The model compensated by raising the value to match the new minimum. Second, we threw a monkey wrench into the model by setting the maximum less than the minimum. However, the bounded-range model adjusted the minimum and the value accordingly to match the newly specified maximum. Now let's try a different tactic: Now setting maximum to 50 . . . A ChangeEvent has been fired! DefaultBoundedRangeModel[value=40, extent=0, min=40, max=50, adj=false] Now setting extent to 30 (greater than max) . . . A ChangeEvent has been fired! DefaultBoundedRangeModel[value=40, extent=10, min=40, max=50, adj=false] Here, we see what happens when we try to set an extent with a subrange greater than the current maximum — the model shortens the extent so that it falls within the bounded range. The same thing occurs if we reset the value of the extent's subrange so that it violates the maximum. Finally, we activate the valueIsAdjusting property to notify any listeners that this is one in a series of changes, and the listener does not need to react immediately: Now setting several properties . . . A ChangeEvent has been fired! DefaultBoundedRangeModel[value=40, extent=10, min=40, max=50, adj=true] A ChangeEvent has been fired! A ChangeEvent has been fired! A ChangeEvent has been fired! A ChangeEvent has been fired! DefaultBoundedRangeModel[value=40, extent=20, min=0, max=100, adj=false] ![]() |
I l@ve RuBoard |
![]() ![]() |