Title: Chapter 18 Integrating user interface and model: the Model-View-Controller pattern
1Chapter 18Integrating user interface and model
the Model-View-Controller pattern
2Objectives
- After studying this chapter you should understand
the following - the Model-View-Controller pattern components and
their roles - the observer pattern, as realized by the class
Observable and interface Observer, and its use in
the MVC pattern. - Also, you should be able to
- write a graphical user interface for a simple
application using the MVC architecture.
3Model-View-Controller
- An Application structure
- model components objects that model and solve
problem - view components objects that display model
- controller components objects that handle user
input.
4Model-View-Controller advantages
- Processing of input and output is separate
- Controllers can be interchanged, allowing
different user interaction modes - Allows multiple views of model.
5M-V-C architecture
6Observer/Observable relationships
- java.util provides class Observable, interface
Observer. - Observer is client and Observable is server.
- Observer registers with the Observable,
- Observable informs Observer when it changes state.
7M-V-C example
- Model a right triangle.
- base and height can be modified.
- Three different views of triangle.
- View one displays lengths of sides.
- View two displays triangle graphically.
- View three logs changes in triangle state to
file. - A controller for view one, to modify triangle.
- No controller for other views.
8RightTriangle class
public class RightTriangle private int
base private int height private int
hypotenuse public RightTriangle (int base,
int height) this.base
base this.height height
setHypotenuse() public int base ()
return this.base public int height
() return this.height
public int hypotenuse () return
this.hypotenuse public void setBase
(int newBase) this.base newBase
setHypotenuse() public void
setHeight (int newHeight) this.height
newHeight setHypotenuse()
private void setHypotenuse ()
this.hypotenuse (int) Math.round(
Math.sqrt(basebase heightheight))
//end RightTriangle.
9Observable methods
- java.util.Observable class specification provides
several methods among those
public void addObserver (Observer o) protected
void setChanged () public void notifyObservers
() public void notifyObservers (Object arg)
10Structuring an Observer/Observable
- RightTriangle extends Observable
public class RightTriangle extends Observable
- All views are Observers of RightTriangle
instance rt - Client Observer registers to rt invoking
addObserver.
rt.addObserver(this)
- When RightTriangle changes state, to notify all
registered observers of the event, modifies
commands to add
setChanged() notifyObservers()
11Implementing an Observable
- RightTriangle changes state in setBase or
setHeight
public void setBase (int newBase) this.base
newBase setHypotenuse() setChanged() notifyO
bservers() public void setHeight (int
newHeight) this.height newHeight setHypoten
use() setChanged() notifyObservers()
12Interface Observer
- interface Observer
- void update (Observable o, Object arg)
13Observer structure
- Observer must know target object.
- Observer registers itself with the target.
- When target notifies observer, observer executes
update.
14A simple view and controller for RightTriangle
- Build a view that shows the three components of
the triangle in text fields. - Controller will capture input from text fields
labeled Base and Height, and modify state of the
RightTriangle appropriately.
15The View
- View extends JPanel and implements Observer.
- RightTriangle to display is provided as
constructor argument.
class TextView extends JPanel implements Observer
private final static int FIELD_SIZE
16 private JTextField base private JTextField
height private JTextField hypotenuse public
TextView (RightTriangle model) super()
base new JTextField(FIELD_SIZE) base.setActio
nCommand("Base") height new
JTextField(FIELD_SIZE) height.setActionCommand(
"Height") hypotenuse new
JTextField(FIELD_SIZE) hypotenuse.setEditable(f
alse)
16The View
- View extends JPanel and implements Observer.
- RightTriangle to display is provided as
constructor argument.
17The View
- When model changes state, notifies view to update
text fields. - Views update queries model for new state
information, and writes it into text fields
public void update (Observable model, Object arg)
int side RightTriangle rt
(RightTriangle)model side rt.base() base.set
Text(String.valueOf(side)) side
rt.height() height.setText(String.valueOf(side))
side rt.hypotenuse() hypotenuse.setText(Str
ing.valueOf(side))
18Controller structure
- Captures user input from base and height text
fields - must have references to the text fields,
- must respond to ActionEvents generated by text
fields, - must be an ActionListener,
- must be added as listener to text fields.
- Updates model.
- This is response to ActionEvent text fields
generate. - Must have reference to RightTriangle.
19Controller structure
private class TVController implements
ActionListener private RightTriangle
model / Create a new controller for this
TextView of the specified RightTriangle.
/ public TVController (RightTriangle model)
this.model model ¹ TextView.this.base.addA
ctionListener(this) TextView.this.height.addAct
ionListener(this)
20Controller structure
/ Update the model in response to user
input. / public void actionPerformed
(ActionEvent e) JTextField tf
(JTextField)e.getSource() try int i
Integer.parseInt(tf.getText()) if (i lt 0)
throw new NumberFormatException() String which
e.getActionCommand() if (which.equals("Base")
) model.setBase(i) else model.setHeight(i
) catch (NumberFormatException ex)
TextView.this.update(model, null)
21Model, View and Controller
22Nim Game Model
23Nim Game TUI
24Nim Game TUI v.s. GUI design
- TUI design
- TUIController
- registers with InteractivePlayer,
- prompts and reads users move, forwards it to
InteractivePlayer. - The play loop is in the interface.
25Nim Game GUI design
26Nim Game TUI v.s. GUI design
- GUI design
- No explicit loop coded.
- User repeats some event.
- NimController
- When user presses an input button it invokes
setNumberToTake on InteractivePlayer. - Invokes Games play,
- once for InteractivePlayer,
- once for IndependentPlayer.
27View
- Display composed of four panels
- a panel to display number of sticks remaining,
- two panels each with a text field to report
players moves, - a panel containing buttons for user to make a
move.
28NimController
29View
- A NimInterface instance
- builds display,
- observes the Game.
30Models Game
- When Game completes a play, it notifies its
Observers.
public void play () if (!gameOver())
nextPlayer.takeTurn(pile,MAX_ON_A_TURN) pre
viousPlayer nextPlayer nextPlayer
otherPlayer(nextPlayer) setChanged() notifyO
bservers()
31GUI structure
- User selects New Game from main menu.
- Menu item listener invokes NimControllers
initializeGame - displays a JDialog to get initialization data
from user, - creates a Game.
32NimInterface
- When notified,
- queries Game,
- updates display.
- NimInterface responsible for
- displaying the number of sticks remaining in the
game - reporting the winner when the game is over.
33Sub-views
- NimInterface
- defines an inner class PlayerView with the
responsibility to report players moves. - A PlayerView observes a Player, and updates the
text field when the Player takes a turn.
34Delaying IdependentPlayers move
- NimController invokes Games play,
- once for InteractivePlayer,
- once for IndependentPlayer.
- Need a delay between the two play invocations.
35Delaying IdependentPlayers move
public void actionPerformed (ActionEvent e)
user.setNumberToTake(number) game.play()
nhUtilities.utilities.Control.sleep(2)
//delay game.play()
- Attempt to delay the two plays fails.
- Application will pause, but moves appear to take
place at the same time.
36Delaying IdependentPlayers move
Event dispatch thread
user presses button
button-press event handler starts
display updates resulting from
InteractivePlayer move are scheduled
thread sleeps for two seconds
display updates resulting form
IndependentPlayer move are scheduled
button-press event handler completes
display is updated
37Scheduling a move to delay the action
- NimController uses javax.swing.Timer to schedule
IndependentPlayers play seconds after play of
InteractivePlayer. - Users Button-press event handling is complete.
- IndependentPlayers move occurs after and when
scheduled.
38MVC and Swing components
- Swing components are structured using MVC
pattern. - Each Swing JComponent has an associated model
object responsible for maintaining components
state. - JButton or JCheckBox has a ButtonModel,
- JTextArea or JTextField has a Document.
- A Swing component delegates view and control
responsibilities to its UI delegate. - The package javax.swing.plaf contains an abstract
delegate class for each Swing component.
39Summary
- Overview basic format of Model-View-Controller
pattern. - MVC commonly used to structure event-driven
graphical user interfaces. - With MVC, interface responsibilities are
partitioned into two segments - view has display responsibilities,
- controller modifies model in accordance with user
input.
40Summary
- Developed three views of a right triangle.
- Noted Java Observer interface and Observable
class for implementing the observes relationship.
- Fundamental relationship between view and model
is observes, implemented by - making model object an extension of the class
Observable, - view implements interface Observer.
- Added a graphical user interface to the nim game,
using the MVC pattern.
41Summary
- Swing components are structured along the lines
of MVC. - Each Swing component has
- an associated model object responsible for
maintaining components state. - a UI delegate, to which view and control
responsibilities are delegated. - This structure allows to change application
look-and-feel in a system-independent way.