dcsimg
December 9, 2016
Hot Topics:

Practical use of MVC in Java 1.2

  • April 9, 1998
  • By Steve Greig, Augie Chung
  • Send Email »
  • More Articles »


Introduction

Design patterns [1] have emerged as one of the leading approaches in achieving the much-hyped re-use benefit of object-oriented design and programming. The Model-View-Controller (MVC) pattern is one of the oldest and most commonly used, particularly within GUI and graphical programming, and its origins can be traced back to the early days of SmallTalk.
Figure 1. Diagram of MVC pattern.

As shown in the preceding diagram, the MVC design pattern is separated into three interacting objects, namely the model, the view and the controller. The model encapsulates the logical representation of the data; the view encapsulates the visual representation; and the controller provides the "glue" that binds the model and view objects together. When the model object changes, it is the controller that notifies all the associated view objects in order that they can update themselves.

By decoupling the data (the model) and the way the data is represented (the view), multiple, yet differing, view objects can represent the same model data. No changes need be made to the model as view representations change or new ones are created.

With Swing [2], Sun has adopted a common, yet powerful, variation on the MVC pattern: combining the view and controller into a single delegate object. This greatly simplifies communication between these two objects, as well as the component design. It is this technique which Sun has used to provide the foundation for the pluggable "look and feel" mechanism. For more complicated and powerful components though, it is clear that the full power of MVC must be utilized.

Through a simple example, we hope to show the fundamentals of building UI components using this powerful approach.

Building a spinner component

Using the techniques described above, we now show how to implement a spinner component that has "pixel for pixel" compatibility with Windows95, as shown below.

Figure 2.

The spinner UI component, which extends Swing's JComponent, acts as both model and controller. This is because the object contains the current value, along with the minimum and maximum values for the spinner. The view contains several UI classes, such as BasicSpinnerUI and JLFSpinnerUI, which provide the basic drawing functionality. Note that when the "look and feel" of Swing 1.0.1 is set to Win32, the spinner control does not have the customary arrow buttons, though with Swing 0.7, the JLFSpinnerUI did have them.

In this example, we extend the "look and feel" of the Swing 1.0.1 spinner component to implement the customary Win32 arrow buttons, placing the functionality inside the UI object -- the view object of the MVC pattern. The source code example below shows the spinner class' setValue() method, called whenever the value is changed.

public void setValue( int v )
{
    // manipulation of the value

    if ( isShowing() )
        repaint( 20 );
    fireAdjustmentValueChanged( new AdjustmentEvent( this, 0,
        AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, v ) );
}

The repaint( 20 ) call ensures that any component that is added by the UI class will be updated, and the JLFSpinnerUI draws the spinner by having a label with the text value drawn and adds the two arrow buttons with "auto repeat" functionality. The call to fireAdjustmentValueChanged( … ) cycles through a list of AdjustmentListeners that have been registered with the Spinner and invokes the adjustmentValueChanged() method. This is part of the Observer-Observable pattern previously mentioned.

Essentially, the spinner has a list of listeners that are interested in the value changing. The JDK 1.1 Event Delegation model provides the foundation for the listeners' event handling; for instance, should the stored value reach either of its range boundaries, the appropriate event can be disabled. This is taken care of within a listener class in the UI class.

The basic spinner control has limited functionality, but with the use of MVC, it has been implemented for maximum extensibility. For example, should we only want the spinner object to show odd integers, we can extend the spinner to use a model, overriding the appropriate methods, so in the case of the setValue() method, it would look like:

public void setValue( int v )
{
    model.setValue( v );  // store the value in the model
    super.setValue( v );  // to fire adjustment value event
}

We can also create two methods -- increment() and decrement() -- which the UI can call to manipulate the value, providing an abstraction of how the value is stored in the model. The logic for manipulating the value would be stored in the model. The following is an example of the increment() method:

public void increment()
{
    int incr = model.increment();  // increment value and return to store
    setValue( incr );              // fires increment value event
}

Building on this approach, we could easily create much more advanced UI controls, decoupling the underlying model implementation. We could, for example, create a time spinner component in one of two ways:

  • use multiple textfields "hidden" in the UI class and have the spinner manage the focus and handle the formatting

  • extend the spinner class to accept strings instead of integers.

The second option is preferred as it lessens confusion with the setValue() methods and so forth. Either way, both examples show that by employing MVC and using a model object, we can encapsulate the underlying dependencies of the way time is implemented within the model, and provide methods, such as increment, to manipulate that value. Access methods, such as getHour(), can also be provided. The benefits gained from MVC are such that we can reuse this class for any other advanced object that needs to work with times.

Conclusions

There are several benefits to employing the MVC architecture, besides the loose coupling of code which facilitates re-use. Our simple example demonstrates how to utilize the much promoted pluggable "look and feel" extensibility of Swing. If, for example, you have created your control to have "pixel for pixel" compatibility with the Windows95 "look and feel", you will need to make some adjustments to use it on Solaris. With the model and controller already in place, all that needs to be changed is the UI class.

As you can see, one small spinner control can open up many different possibilities. Imagine what other more advanced components could be developed.

References

  1. "Design Patterns: Elements of Reusable Object Oriented Software", E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Addison-Wesley Publishing Company, 1995.

  2. "What's New With Java?", Steve Greig and Augie Chung, developer.com, 1998.
Download the complete source code for this example from a zip file.

Steve Greig is a member of the technical consulting staff at Mercury Technologies specializing in object oriented design and project management.

Augie Chung is a technical consultant for Internet Software Solutions specializing in Java development and advanced GUI design.







Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date
Rocket Fuel