Table of Contents Markup Tutorial Interfacing with Java™ Web Services

Here, the MVC pattern is illustrated with the help of a simple spinner component which consists of a text field and two arrow buttons that can be used to increment or decrement a numeric value shown in the text field.

Note: The design presented here is based completely on custom classes and interfaces. If your code is destined exclusively for JRE 1.4 or later, you might consider using the new JSpinner class introduced in JRE version 1.4. You can realize an instance of that class by using an object element whose class attribute is set to the value javax.swing.JSpinner.

Even if you decide to use javax.swing.JSpinner, you should still look at the following example to learn how to set up model, view, and controller objects and to fire user-defined events.

Spinner Structure

A spinner and its supporting objects are shown in the following illustration:

As shown in this diagram, a spinner requires two specialized objects — an action listener and a model. The model holds the spinner’s data and is shared with the text field. The action listener handles events from the buttons and, depending on the source of an event, either increments or decrements the spinner’s value held in the model.

The model and controller are implemented by the classes com.enode.xalt.IntegerTextModel, and com.enode.xalt.Sequencer, respectively. The model is attached to the controller through the latter’s sequence property, and is also shared by the text field. The model may also be configured through its maximum, minimum, stepSize, and value properties, all of which are optional. Finally, the “up” and “down” buttons are associated with actions that act as trampolines — bouncing action events off to the controller.

Let us quickly test our objects with the following markup without worrying about the precise layout of the view:

Make this object in eNode Sandbox. The result should be similar to the following:

The controller is described using an object element whose class attribute is set to the value com.enode.xalt.Sequencer. Since the controller is an action listener, we would have preferred to use the actionListener element type. But because we have to attach the model to the controller through the latter’s sequence property, we have to use the object element type to represent the controller in this case. This is because only the object element type has built-in support for bean properties.

For the same reason, the text model is described using an object element instead of a more direct textModel element. Some of the model’s properties are described using int elements which can specify an integer value through their value attribute.

Conventional Spinner

By changing the icons for the buttons, and making small changes to the layout, we get the conventional spinner arrangement with little arrows to the right of the text field. For good measure, we also adorn the entire spinner with a raised bevel border.

Make this object in eNode Sandbox. The result should be similar to the following:

Editing Through the Text Field

Note that it is possible to enter non-numeric data by directly typing into the text field. That is because we haven’t implemented the action listener for the text field itself. That action listener, represented graphically on the left in the following illustration, is left as an exercise for you. Depending on the policy you want to implement, it should either revert the data in the model to the last valid value, or to a preset default. Either way, it should commit only legal values to the model.

If you want a really cheap way out of this predicament, you can set the textField element’s editable attribute to false. Users will still be able to change the value using the buttons, but they will not be able to type directly into the field. If you adopt this approach, make sure that doing so does not compromise the usability of your application.


Copyright © 2002 eNode, Inc. All Rights Reserved.