6.1 The Bounded-Range Model


Components 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
figs/swng2.0601.gif

6.1.1 Properties

Table 6-1 shows the properties of the BoundedRangeModel interface.

Table 6-1. BoundedRangeModel properties

Property

Data type

get

is

set

Default value

extent

int

·

 

·

 

maximum

int

·

 

·

 

minimum

int

·

 

·

 

value

int

·

 

·

 

valueIsAdjusting

boolean

·

 

·

 

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
figs/swng2.0602.gif

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:

  • If the user sets a new value that is outside the bounded range, the value is set to the closest boundary (minimum or maximum).

  • If the user sets a new value so that extent exceeds the maximum, the model resets the value to the amount of the maximum minus the extent thus preserving the width of the extent.

  • If the user sets extent to a negative number, it is reset to 0.

  • If the user sets extent large enough to exceed the maximum, the model resets extent to be the remaining width, if any, between the model's current value and its maximum.

  • If the user resets the minimum or maximum so that the model's value now falls outside the bounded range, the value is adjusted to become the boundary closest to its original value.

  • If a user resets a minimum so that it exceeds the maximum, the maximum and the value are reset to the new minimum. Conversely, if a new maximum is less than the current minimum, the minimum and value are adjusted to be the new maximum. In both cases, extent is reset to 0.

  • If the user resets a minimum or maximum so that extent goes beyond the maximum, extent is decreased so it does not exceed the maximum.

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 Events

Objects 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.

public abstract void addChangeListener(ChangeListener 1)
public abstract void removeChangeListener(ChangeListener 1)

Add or remove a ChangeListener for receiving events when a property changes.

6.1.3 Method

public abstract void setRangeProperties(int value, int extent, int min, int max,boolean adjusting)

Typically, one event is generated per property change. However, if you wish to make multiple changes without triggering events, you can call the setRangeProperties( ) method to change all five properties at once. This method generates a single ChangeEvent per call. For example:

setRangeProperties(40, 4, 32, 212, false); // Generates a single change event

6.1.4 The DefaultBoundedRangeModel Class

Swing 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 Properties

The 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.

Table 6-2. DefaultBoundedRangeModel properties

Property

Data type

get

is

set

Default value

changeListeners1.4

ChangeListener[]

·

   

Empty array

extento

int

·

 

·

0

maximumo

int

·

 

·

100

minimumo

int

·

 

·

0

valueo

int

·

 

·

0

valueIsAdjustingo

boolean

·

 

·

false

1.4since 1.4, ooverridden

6.1.4.2 Events

As specified by the bounded-range interface, the DefaultBoundedRangeModel fires a ChangeEvent when the model modifies its minimum, maximum, value, or extent properties.

public void addChangeListener(ChangeListener l)
public void removeChangeListener(ChangeListener l)

Add or remove a change listener from the list of objects that receive a ChangeEvent when a property changes.

public EventListener[] getListeners(Class listenerType)

This method was introduced in SDK 1.3 as a way of learning about the registered listeners. The changeListeners property added in 1.4 is a more convenient way to get the same information.

6.1.4.3 Constructors
public DefaultBoundedRangeModel( )

The default constructor for this class. It initializes a bounded-range model with a minimum of 0, a maximum of 100, and a value and extent of 0.

public DefaultBoundedRangeModel(int value, int extent, int minimum, int maximum)

Initialize the bounded-range model with the specified values.

6.1.4.4 Working with the bounded-range model

Here 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]


Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net