Upload
kelsey-hurley
View
28
Download
2
Embed Size (px)
DESCRIPTION
Chapter 18 Integrating user interface and model: the Model-View-Controller pattern. Objectives. After studying this chapter you should understand the following: the Model-View-Controller pattern: components and their roles; - PowerPoint PPT Presentation
Citation preview
An Introduction to Programming and Object
Oriented Design using Java2nd Edition. May 2004
Jaime NiñoFrederick Hosch
Chapter 18Integrating user interface and model:
the Model-View-Controller pattern
2May 2004 NH-Chapter 18
Objectives
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.
3May 2004 NH-Chapter 18
Model-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.
4May 2004 NH-Chapter 18
Model-View-Controller advantages
Processing of input and output is separate;
Controllers can be interchanged, allowing different user interaction modes;
Allows multiple views of model.
5May 2004 NH-Chapter 18
M-V-C architecture
Model
Controller control1
Controller control2
View view1
View view2
View view3
6May 2004 NH-Chapter 18
Observer/Observable relationships
Observer
SomeClient
«interface»Observable
notifies
registers with
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.
7May 2004 NH-Chapter 18
M-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.
8May 2004 NH-Chapter 18
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(base*base + height*height)); }}//end RightTriangle.
RightTriangle class
9May 2004 NH-Chapter 18
Observable methods
public void addObserver (Observer o);
protected void setChanged ();
public void notifyObservers ();
public void notifyObservers (Object arg);
java.util.Observable class specification provides several methods; among those:
10May 2004 NH-Chapter 18
When RightTriangle changes state, to notify all registered observers of the event, modifies commands to add:
Structuring an Observer/ObservableRightTriangle extends Observable:
public class RightTriangle extends Observable …
All views are Observer’s of RightTriangle instance rt
Client Observer registers to rt invoking addObserver.
rt.addObserver(this);
setChanged();
notifyObservers();
11May 2004 NH-Chapter 18
Implementing an Observable
RightTriangle changes state in setBase or setHeight :
public void setBase (int newBase) {
this.base = newBase;
setHypotenuse();
setChanged();
notifyObservers();
}
public void setHeight (int newHeight) {
this.height = newHeight;
setHypotenuse();
setChanged();
notifyObservers();
}
12May 2004 NH-Chapter 18
Interface Observer
interface Observer {
void update (Observable o, Object arg);
}
13May 2004 NH-Chapter 18
Observer structure
class RTObserver implements Observer {private RightTriangle target;
// Create an observer of RightTriangle rt.public RTObserver (RightTriangle rt) {
target = rt;target.addObserver(this);…
}
public void update((Observable o, Object arg){ do something about o’s state
change.}…
}
observer registers with model
Observer must know target object. Observer registers itself with the target. When target notifies observer, observer executes update.
14May 2004 NH-Chapter 18
A 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.
15May 2004 NH-Chapter 18
The 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.setActionCommand("Base");…height = new JTextField(FIELD_SIZE);height.setActionCommand("Height");…hypotenuse = new JTextField(FIELD_SIZE);hypotenuse.setEditable(false);…
}
16May 2004 NH-Chapter 18
The View View extends JPanel and implements Observer. RightTriangle to display is provided as constructor argument.
17May 2004 NH-Chapter 18
The View When model changes state, notifies view to update text fields. View’s 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.setText(String.valueOf(side));side = rt.height();height.setText(String.valueOf(side));side = rt.hypotenuse();hypotenuse.setText(String.valueOf(side));
}
18May 2004 NH-Chapter 18
Controller 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.
19May 2004 NH-Chapter 18
Controller structureprivate 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.addActionListener(this);
TextView.this.height.addActionListener(this);}
20May 2004 NH-Chapter 18
Controller 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 < 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);}
}
21May 2004 NH-Chapter 18
Model, View and Controller
JTextField RightTriangle
hasTextView
TVController
listens-to
observes
modifies
2
3
22May 2004 NH-Chapter 18
Nim Game : Model
Player
«interface»
IndependentPlayerInteractivePlayer
AbstractPlayer
Game Pile
directs
provides
2
us
es
23May 2004 NH-Chapter 18
Nim Game : TUI
NimGame
creates
NimTUI
Gamecreates
creates
InteractiveController
TUIController
«interface»InteractivePlayer
notifies
provides moves
Player
«interface»
24May 2004 NH-Chapter 18
Nim Game : TUI v.s. GUI design
TUI design: TUIController
registers with InteractivePlayer, prompts and reads user’s move, forwards it to InteractivePlayer.
The play loop is in the interface.
25May 2004 NH-Chapter 18
Nim Game : GUI design
Observer
NimInterface
«interface»Observable
observes
Game
26May 2004 NH-Chapter 18
Nim 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 Game’s play, once for InteractivePlayer, once for IndependentPlayer.
27May 2004 NH-Chapter 18
View
Display composed of four panels: a panel to display number of sticks remaining, two panels each with a text field to report player’s moves, a panel containing buttons for user to make a move.
28May 2004 NH-Chapter 18
NimController
provides moves
Game
InteractivePlayer
NimInterface.NimController
directs play
JButtonlistens to 3
29May 2004 NH-Chapter 18
View
A NimInterface instance: builds display, observes the Game.
30May 2004 NH-Chapter 18
Model’s Game
When Game completes a play, it notifies its Observers.
public void play () {
if (!gameOver()) {
nextPlayer.takeTurn(pile,MAX_ON_A_TURN);
previousPlayer = nextPlayer;
nextPlayer = otherPlayer(nextPlayer);
setChanged();
notifyObservers();
}
}
31May 2004 NH-Chapter 18
GUI structure User selects “New Game” from main menu.
Menu item listener invokes NimController’s initializeGame: displays a JDialog to get initialization data from user, creates a Game.
32May 2004 NH-Chapter 18
NimInterface
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.
33May 2004 NH-Chapter 18
Sub-views
NimInterface defines an inner class PlayerView with the responsibility to report
player’s moves.
A PlayerView observes a Player, and updates the text field when the Player takes a turn.
NimInterface.PlayerViewobserves
Player
«interface»
34May 2004 NH-Chapter 18
Delaying IdependentPlayer’s move
NimController invokes Game’s play, once for InteractivePlayer, once for IndependentPlayer.
Need a delay between the two play invocations.
35May 2004 NH-Chapter 18
Delaying IdependentPlayer’s move
Attempt to delay the two plays fails. Application will pause, but moves appear to take place at the
same time.
public void actionPerformed (ActionEvent e) {
…
user.setNumberToTake(number);
game.play();
nhUtilities.utilities.Control.sleep(2); //delay
game.play();
…
}
36May 2004 NH-Chapter 18
Delaying IdependentPlayer’s move
user presses button
thread sleeps for two seconds
display updates resulting form
display is updated
display updates resulting fromInteractivePlayer move are scheduled
IndependentPlayer move are scheduled
button-press event handler starts
button-press event handler completes
Event dispatch thread
37May 2004 NH-Chapter 18
Scheduling a move to delay the action
NimController uses javax.swing.Timer to schedule IndependentPlayer’s play seconds after play of InteractivePlayer.
User’s Button-press event handling is complete.
IndependentPlayer’s move occurs after and when scheduled.
38May 2004 NH-Chapter 18
MVC and Swing components
Swing components are structured using MVC pattern.
Each Swing JComponent has an associated model object responsible for maintaining component’s 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.
39May 2004 NH-Chapter 18
Summary
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.
40May 2004 NH-Chapter 18
Summary
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.
41May 2004 NH-Chapter 18
Summary
Swing components are structured along the lines of MVC.
Each Swing component has an associated model object responsible for maintaining
component’s 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.