Designing Swing Components with the Model Interface
MVC divides a graphical component into Model, View, and Controller so that each object has one clearly defined role.
A Volume Slider With Too Many Jobs
Imagine building a volume slider for a music app. The slider must remember how loud the volume currently is, draw itself on the screen at the right position, and react when someone drags it. You could write all of that inside one large object. For a toy example that works, but it becomes hard to change the way the slider looks without accidentally breaking the way it stores its value, or the reverse. The Model-View-Controller pattern, usually called MVC, is the design answer to that problem. This article follows one component through its three realms so you can see what each one owns and how they cooperate.
What do you think happens?
When a user drags the slider knob, does the drawing part of the component change the stored value directly, or does some other part handle that job first?
Reveal answer
Another part handles the drag first and changes the stored value. The controller responds to the event by modifying the model, and the view is updated only indirectly afterward.
The source describes user input as something that does not paint pixels directly. It changes data, and the change is then shown. The controller is the part that responds to input, and the view reacts to the resulting change in the model.
Why Three Realms Instead of One
MVC starts from a general principle of object-oriented design: an object should have one clearly defined role with a limited realm of responsibility. Applied to graphical user interfaces, that principle produces three realms. MVC is short for Model-View-Controller, and each name labels one of those realms. The Model stores the current state of the component. The View draws that state on the screen by consulting the Model. The Controller responds to user and other events, usually by modifying the Model rather than drawing anything itself.
Model-View-Controller (MVC) is a way of dividing a graphical component into three objects with clearly separated roles: the Model holds state, the View presents that state, and the Controller handles events and changes the Model.
The three roles can be remembered through three distinctions. State is what the component knows, which belongs to the Model. Presentation is how that knowledge appears on screen, which belongs to the View. Event handling is how user actions and other happenings are received and acted on, which belongs to the Controller. Keeping these distinctions apart means a change to appearance does not have to touch the stored value, and a change to the stored value does not force a rewrite of the drawing code.
Where the Volume Value Lives
For the slider, the Model is the place where the current volume value lives. The Model does not draw anything and does not decide what to do when a mouse moves. It only holds the data and keeps it accurate. Because the state sits in its own object, any other part of the component that needs to know the volume asks the Model for it rather than keeping a separate copy that could fall out of step.
The Model also has one further job in this design. The source says the Model is set up to generate events when its data changes. The Model does not need to know how the View draws things. It only announces that its data has changed, and the View decides how to respond.
Read the diagram as a chain of hand-offs. The stored value changes first, inside the Model. The Model then announces the change through an event. The View receives that announcement and repaints. At no point does the Model call the View's drawing code by name, which is what keeps the two realms separate.
The View as a Reader of State
The source notes that the View is often the component object itself, which makes it the easiest of the three parts to recognize. To draw correctly, the View has to consult the Model, because the Model holds the state and that state determines what appears on screen. For the slider, the drawn knob position depends on the volume value stored in the Model. The View therefore keeps a reference to the Model object so it can read the data when it paints.
The Controller as the Event Handler
The Controller is the least tidy of the three realms when MVC is used for Swing components. The source explains that its responsibilities are often split among several objects rather than gathered into one. These can include mouse and keyboard listeners that respond to user input on the View, action objects that respond to menu commands or buttons, and listeners for higher-level events such as those produced by a slider. Each of these pieces responds to something happening, and each one ultimately changes the state of the component.
Notice what the Controller does not do. In the typical pattern it responds to an event by modifying the Model, and it does not paint anything itself. When you see a piece of code that both reacts to a mouse drag and draws the knob, you are looking at responsibilities that the pattern asks you to separate.
Following One Drag From Start to Finish
The sequence below traces one complete update. Each arrow is an ordered message. Read it from top to bottom, starting with the user's drag, and notice that the View's final step is a read of the Model rather than a fresh calculation of the volume.
Tracing one drag step by step
The volume is 40. The user drags the knob up to a position that corresponds to 55. Trace which part handles each step.
- 1Step 1: the user drags
The mouse input arrives as an event. The user never touches the stored value directly.
- 2Step 2: the Controller responds
The Controller receives the event and modifies the Model so that the volume value becomes 55. It does not paint the knob.
- 3Step 3: the Model announces the change
Because its data changed, the Model generates an event. The Model does not know how the knob will be drawn.
- 4Step 4: the View updates
The View, registered as a listener, is notified. It reads the new volume from the Model and repaints the knob at the position for 55.
The stored value moved from 40 to 55 through the Model, and the knob appeared at its new position through the View. No single object did both the storing and the drawing.
Assigning Responsibilities in a Slider
The most useful skill this pattern gives you is deciding where a responsibility belongs. Use the three distinctions from earlier. Ask whether the thing is stored knowledge, whether it is a matter of how something appears, or whether it is a reaction to something that happened.
| Part | Owns | Does not own | Slider example |
|---|---|---|---|
| Model | The current state of the component | Drawing, mouse handling | The stored volume value |
| View | Presentation on the screen | Owning the value, deciding it alone | The drawn knob position |
| Controller | Responding to events and modifying the Model | Painting pixels directly | Reacting to a drag and updating the volume |
Which part owns which responsibility in a simple slider
Mistakes When Splitting the Three Roles
Common mistake Letting the View change the stored value when the user interacts
What it looks likeThe drawing code for the knob also sets the volume when it sees a mouse press.
Why it failsThe View is responsible for presentation. The source says user input changes data through the Controller, and the View then reflects the change.
Do this insteadMove the reaction to input into the Controller, which modifies the Model. Let the View only read and draw.
Common mistake Keeping a second copy of the volume inside the View
What it looks likeThe knob object stores its own number that is set alongside the Model's value.
Why it failsThe source explains that the state sits in its own object so other parts ask the Model rather than keeping a separate copy that could fall out of step.
Do this insteadHave the View read the value from the Model whenever it paints.
Common mistake Having the Model call the View's drawing code directly
Why it failsThe source says the Model only announces that its data has changed, and the View decides how to respond. A direct call would tie the Model to one particular presentation.
Do this insteadHave the Model generate a change event, and let the View register as a listener and repaint.
Common mistake Assuming the Controller is always a single object; in Swing its responsibilities are often split among several listeners and action objects
Test Your Assignment
A button in a simple GUI has a pressed status that is true while the mouse is held down on it, and it shows a darker color while pressed. For each of these three items, say whether it belongs to the Model, the View, or the Controller, and explain your choice using the state, presentation, or event-handling distinction: (a) the pressed status, (b) the darker color drawn on screen, (c) the code that responds to the mouse press.
Hints
- Ask whether the item is stored knowledge about the component, a matter of how it appears, or a reaction to something happening.
- The pressed status is state the component must remember, so think about where the source places stored state.
- The source says the Controller usually changes the Model in response to an event rather than drawing anything itself.
Key Takeaways
- MVC divides a graphical component into Model, View, and Controller so that each object has one clearly defined role: the Model holds state, the View presents it, and the Controller handles events.
- The Controller usually responds to input by modifying the Model, and the View is updated only indirectly when the Model announces a change through an event.
- The View reads state from the Model when it draws, rather than owning the value itself, which keeps the stored data separate from its presentation.
- In Swing, the Controller's responsibilities are often spread across several listener and action objects, so assigning responsibilities means asking whether each one is state, presentation, or event handling.