The Model-View-Controller Architecture

Một phần của tài liệu the definitive guidae to java swing (Trang 81 - 88)

The Model-View-Controller Architecture

Chapter 2 explored how to deal with event producers and consumers with regard to Swing components. We looked at how event handling with Swing components goes beyond the event-handling capabilities of the original AWT components. In this chapter, we will take the Swing component design one step further to examine what is called the Model-View-Controller (MVC) architecture.

Understanding the Flow of MVC

First introduced in Smalltalk in the late 1980s, the MVC architecture is a special form of the Observer pattern described in Chapter 2. The model part of the MVC holds the state of a component and serves as the Subject. The view part of the MVC serves as the Observer of the Subject to display the model’s state. The view creates the controller, which defines how the user interface reacts to user input.

MVC Communication

Figure 3-1 shows how the MVC elements communicate—in this case, with Swing’s multiline text component, the JTextArea. In MVC terms, the JTextArea serves as the view part within the MVC architecture. Displayed within the component is a Document, which is the model for the JTextArea. The Document stores the state information for the JTextArea, such as the text contents.

Within the JTextArea is the controller, in the form of an InputMap. It maps keyboard input to commands in an ActionMap, and those commands are mapped to TextAction objects, which can modify the Document. When the modification happens, the Document creates a

DocumentEvent and sends it back to the JTextArea.

60 C H A P T E R 3 ■ T H E M O D E L - V I E W - C O N T R O L L E R A R C H I T E C T U R E

Figure 3-1. MVC communication mechanism

UI Delegates for Swing Components

This example demonstrates an important aspect of the MVC architecture within the Swing world. Complex interactions need to happen between the view and the controller. The Swing design combines these two elements into a delegate object to simplify the overall design. This results in each Swing component having a UI delegate that is in charge of rendering the current state of the component and dealing with user input events.

Sometimes, the user events result in changes to the view that don’t affect the model. For instance, the cursor position is an attribute of the view. The model doesn’t care about the posi- tion of the cursor, only the text contents. User input that affects the cursor position isn’t passed along to the model. At other times, user input that affects the contents of the Document (for example, pressing the Backspace key) is passed along. Pressing the Backspace key results in a character being removed from the model. Because of this tight coupling, each Swing component has a UI delegate.

To demonstrate, Figure 3-2 shows the makeup of the JTextArea, with respect to the model and UI delegate. The UI delegate for the JTextArea starts with the TextUI interface, with its basic implementation in the BasicTextUI class. In turn, this is specialized with the BasicTextAreaUI for the JTextArea. The BasicTextAreaUI creates a view that is either a PlainView or a WrappedPlainView. On the model side, things are much simpler. The Document interface is implemented by the AbstractDocument class, which is further specialized by the PlainDocument.

The text components will be explained more fully in Chapters 15 and 16. As the diagram in Figure 3-2 demonstrates, much is involved in working with the text components. In most cases, you don’t need to deal with the specifics to the degree shown in this figure. However, all of these classes are working behind the scenes. The UI-delegate part of the MVC architecture will be discussed further in Chapter 20, when we explore how to customize delegates.

C H A P T E R 3 ■ T H E M O D E L - V I E W - C O N T R O L L E R A R C H I T E C T U R E 61

Figure 3-2. The JTextArea MVC architecture

Sharing Data Models

Because data models store only the state information, you can share a model across multiple components. Then each component view can be used to modify the model.

In the case of Figure 3-3, three different JTextArea components are used to modify one Document model. If a user modifies the contents of one JTextArea, the model is changed, causing the other text areas to automatically reflect the updated document state. It isn’t necessary for any Document view to manually notify others sharing the model.

62 C H A P T E R 3 ■ T H E M O D E L - V I E W - C O N T R O L L E R A R C H I T E C T U R E

Figure 3-3. Sharing MVC data models

Sharing of a data model can be done in either one of two ways:

• You can create the data model apart from any component and tell each component to use the data model.

• You can create one component first, get the model from the first component, and then share it with the other components.

Listing 3-1 demonstrates how to share a data model using the latter technique.

Listing 3-1. Sharing an MVC Model

import java.awt.*;

import javax.swing.*;

import javax.swing.text.*;

public class ShareModel {

public static void main (String args[]) { Runnable runner = new Runnable() { public void run() {

JFrame frame = new JFrame("Sharing Sample");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Container content = frame.getContentPane();

JTextArea textarea1 = new JTextArea();

Document document = textarea1.getDocument();

JTextArea textarea2 = new JTextArea(document);

JTextArea textarea3 = new JTextArea(document);

content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));

content.add(new JScrollPane(textarea1));

C H A P T E R 3 ■ T H E M O D E L - V I E W - C O N T R O L L E R A R C H I T E C T U R E 63

content.add(new JScrollPane(textarea2));

content.add(new JScrollPane(textarea3));

frame.setSize (300, 400);

frame.setVisible (true);

} };

EventQueue.invokeLater(runner);

} }

Figure 3-4 shows how this program might look after editing the shared document. Notice that the three text areas are capable of viewing (or modifying) different areas of the document.

They aren’t limited to adding text only at the end, for instance. This is because each text area manages the position and cursor separately. The position and cursor are attributes of the view, not the model.

Figure 3-4. Sharing a document between JTextArea components

Understanding the Predefined Data Models

When working with Swing components, it’s helpful to understand the data models behind each of the components because the data models store their state. Understanding the data model for each component helps you to separate the parts of the component that are visual (and thus part of the view) from those that are logical (and thus part of the data model). For example, by understanding this separation, you can see why the cursor position within a JTextArea isn’t part of the data model, but rather is part of the view.

Table 3-1 provides a complete listing of the Swing components, the interface that describes the data model for each component, as well as the specific implementations. If a component isn’t listed, that component inherits its data model from its parent class, most likely

64 C H A P T E R 3 ■ T H E M O D E L - V I E W - C O N T R O L L E R A R C H I T E C T U R E

AbstractButton. In addition, in some cases, multiple interfaces are used to describe a compo- nent, because the data is stored in one model and the selection of the data is in a second model.

In the case of the JComboBox, the MutableComboBoxModel interface extends from ComboBoxModel.

No predefined class implements the ComboBoxModel interface without also implementing the MutableComboBoxModel interface.

Table 3-1. Swing Component Models

Component Data Model Interface Implementations

AbstractButton ButtonModel DefaultButtonModel

JColorChooser ColorSelectionModel DefaultColorSelectionModel

JComboBox ComboBoxModel N/A

MutableComboBoxModel DefaultComboBoxModel

JFileChooser ListModel BasicDirectoryModel

JList ListModel AbstractListModel

DefaultListModel

ListSelectionModel DefaultListSelectionModel JMenuBar SingleSelectionModel DefaultSingleSelectionModel JPopupMenu SingleSelectionModel DefaultSingleSelectionModel JProgressBar BoundedRangeModel DefaultBoundedRangeModel JScrollBar BoundedRangeModel DefaultBoundedRangeModel JSlider BoundedRangeModel DefaultBoundedRangeModel

JSpinner SpinnerModel AbstractSpinnerModel

SpinnerDateModel SpinnerListModel SpinnerNumberModel

JTabbedPane SingleSelectionModel DefaultSingleSelectionModel

JTable TableModel AbstractTableModel

DefaultTableModel TableColumnModel DefaultTableColumnModel ListSelectionModel DefaultListSelectionModel

JTextComponent Document AbstractDocument

PlainDocument StyledDocument DefaultStyleDocument HTMLDocument

C H A P T E R 3 ■ T H E M O D E L - V I E W - C O N T R O L L E R A R C H I T E C T U R E 65

When directly accessing the model of a Swing component, if you change the model, all registered views are automatically notified. This, in turn, causes the views to revalidate them- selves to ensure that the components display their proper current states. This automatic propagation of state changes is one reason why MVC has become so popular. In addition, using the MVC architecture helps programs become more maintainable as they change over time and their complexity grows. No longer will you need to worry about losing state informa- tion if you change visual component libraries!

Summary

This chapter provided a quick look at how the Swing components use a modified MVC archi- tecture. You explored what makes up this modified architecture and how one particular component, the JTextArea, maps into this architecture. In addition, the chapter discussed the sharing of data models between components and listed all the data models for the different Swing components.

In Chapter 4, you’ll start to look at the individual components that make up the Swing component library. In addition, you’ll explore the Swing component class hierarchy as you examine the base JComponent component from the Swing library.

JToggleButton ButtonModel JToggleButton

ToggleButtonModel

JTree TreeModel DefaultTreeModel

TreeSelectionModel DefaultTreeSelectionModel JTree.EmptySelectionModel Table 3-1. Swing Component Models (Continued)

Component Data Model Interface Implementations

67

■ ■ ■

Một phần của tài liệu the definitive guidae to java swing (Trang 81 - 88)

Tải bản đầy đủ (PDF)

(912 trang)