![]() |
![]() |
||||||
|
|||||||
Object composition using markup is often more flexible than using a component that is frozen at compile time. As an example, consider what you would have to do to the spinner example if you wanted the numeric text field to increase or decrease monotonically. All you have to do in your markup is simply not define the unnecessary button and action elements! Combo Box Spinner With very little effort, it is possible to compose a new type of object by reusing much of the code from the last example. Instead of a spinner with a numeric text field, the following example shows how to set up a spinner that uses a combo box containing names of months. Also, unlike the numeric spinner, which stops incrementing or decrementing beyond its range, this spinner cycles through its values at either end of the range. We first present the markup, and then explain the code. Make this object in eNode Sandbox. The result should be similar to the following: ![]() Compare the above markup with that of this spinner example, and see how much of the code is reused. Specifically, we reuse the controller class com.enode.xalt.Sequencer without any modifications. Obviously, the textField element has to be replaced by a comboBox element. So, the only significant change in this example is the use of com.enode.calendar.MonthModel as the model class. Model Class We define our combo box model class by extending javax.swing.DefaultComboBoxModel, and implementing the com.enode.calendar.MonthSequence interface. The latter is a nominal extension of com.enode.Sequence that does not declare any new methods or properties. We call this combo box model class com.enode.calendar.MonthModel because we envision that it will be used to store names of months only. We now show the listing for the model class. The constructor of the model class invokes its superclass’ constructor with an array of month names obtained from an instance of java.text.DateFormatSymbols. To accommodate non-Gregorian calendars, that class allocates an array that has more than twelve entries. To keep this example simple, we assume that we will always be working with a Gregorian calendar — So, we just loop through the model entries, and remove any superfluous entries from the end. The value of the spinner can be “incremented” or “decremented” using the arrow buttons on either side of the combo box, or can be set directly by selecting an item from the combo box. In either case, we must make sure that the value maintained by the spinner’ model agrees with the item shown in the combo box. To accomplish this, we override the setSelectedItem() method of DefaultComboBoxModel to invoke changeSequence(), a private method, which, in turn, invokes the superclass version of setSelectedItem(). The changeSequence() method concludes by synchronizing the spinner’s value with the combo box’s selected item, and firing a user-defined event called com.enode.xalt.SequenceChangeEvent. The events infrastructure is identical to that described in the numeric spinner example. Propagating Event Information As previously mentioned, the value of the spinner can be changed either directly through the combo box, or by using the arrow buttons that flank the combo box on its left and right. Most of the time, it should not matter how the value was changed, but at other times that information may be significant, and must somehow be captured. In this example, that information is passed into the fireSequenceChanged() method, where it is subsequently captured by invoking the setChangeType() method on the event object. The event information is eventually propagated to each listener through sequenceChanged() notifications. |
|||||||
|
Copyright © 2002 eNode, Inc. All Rights Reserved. |