The Bounded-Range Model

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.
 
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.
nbsp;
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.

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]