chapter 19
DESCRIPTION
Chapter 19. Designing the GUI front-end: the Model-View-Controller pattern. This chapter discusses. The Model-View-Controller (MVC) Two components: View and Controller. Implementing MVC and the observes relation in Java. Basic Swing components structured along the lines of the MVC pattern. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/1.jpg)
Chapter 19Designing the GUI front-end: the Model-View-Controller pattern
![Page 2: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/2.jpg)
This chapter discusses
The Model-View-Controller (MVC) Two components: View and
Controller. Implementing MVC and the
observes relation in Java. Basic Swing components
structured along the lines of the MVC pattern
![Page 3: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/3.jpg)
Model-View-Controller
model components -- the objects that model and solve the problem at hand.
view components -- the objects that determine the manner in which the model components are to be displayed.
controller components -- the objects that handle user input.
![Page 4: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/4.jpg)
Advantages Input processing is separated from
output processing. Controllers can be interchanged,
allowing different user interaction modes. Multiple views of the model can be
supported easily.
![Page 5: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/5.jpg)
Model
The model does not require details of the other components.
The model is independent. The model can be retrofitted
readily with a new look and feel.
![Page 6: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/6.jpg)
View
The view must insure that the display accurately reflects the current state of the model.
The view is an observer, notified of state changes in a target (model).
The view-controller relationship is often has-as-strategy.
View is often a composite built of simpler views.
![Page 7: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/7.jpg)
Controller
The controller defines how the view responds to user input.
The controller must effect changes in the model as determined by user input.
The controller listens to the view or its components.
![Page 8: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/8.jpg)
Example
Let’s consider a system that models a right triangle.
It accepts base and height and calculates the hypotenuse.
![Page 9: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/9.jpg)
Example: Modelpublic class RightTriangle {
//Contructors/** * Create right triangle with base and height * require: * base>=0; height >= 0 */public RightTriangle (int base, int height) { this.base = base; this.height = height; setHypotenuse();}//Queries/** * The base * ensure: * result >= 0; */public int base() { return this.base;}
![Page 10: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/10.jpg)
Example: Model (cont.)/** * The height * ensure: * result >= 0; */
public int height() { return this.height;}/** * The hypotenuse * ensure: * result >= 0; */
public int hypotenuse() { return this.hypotenuse;}//Commands/** * Change base * require: * newBase>= 0; */
public void setBase(int newBase) { this.base = newBase; setHypotenuse();}
![Page 11: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/11.jpg)
Example: Model (cont.)public void setHeight(int newHeight) { this.height = newHeight; setHypotenuse();}//Private Methods/** * Adjust hypotenuse */
public void setHypotenuse() { this.hypotenuse = (int) Math.round(
Math.sqrt(base*base + height*height));}//Private Methods
private int base;private int height;private int hypotenuse;
}
![Page 12: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/12.jpg)
Observer To support the observes relation, Java provides a
class Observable and an interface Observer in the package java.util.
Observable methods:public void addObserver(Observer o);
protected void setChanged ();
public void notifyObservers ();
public void notifyObservers (Object arg); Class component:private boolean haschanged;private ObserverList observers;
![Page 13: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/13.jpg)
Example:Model (cont.)public class RightTriangle extends Observable
{…public void setBase (int newBase) { this.base = newBase; setHypotenuse(); setChanged(); notifyObservers();}public void setHeight (int newHeight) { this.height = newHeight; setHypotenuse(); setChanged(); notifyObservers();}…
}
![Page 14: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/14.jpg)
Example:Observer
class RTObserver implements Observer {
public RTObserver (RightTriangle rt) {
target = rt;
target.addObserver(this);
}
…
private RightTriangle target;
}
![Page 15: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/15.jpg)
Observer
The interface Observer specifies only one method:
void update (Observable o, Object arg);
The first parameter references the target; the second is the argument provided by the target to
notifyObservers. Called by the target to notify the observer of a state
change
notifyObservers(info); causes the update method of each of its observers to be
called.
![Page 16: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/16.jpg)
Observer (cont.)public class Observable () {
public Observable () { observer = new ObserverList(); hasChanged = false;}
public void addObserver (Observer o) { observer.append(o);}
public void setChanged () { hasChanged = true;}
![Page 17: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/17.jpg)
Observer (cont.)public void notifyObservers(Object arg){ if (hasChanged) {
int i;int len = observers.size();for (i = 0; i < len; i = i+1)((Observer)observers.get(i)).update(
this, arg); hasChanged = false;
}}
public void notifyObservers () { this.notifyObservers(null);}
private boolean hasChanged;private ObserverList observers;
}
![Page 18: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/18.jpg)
Example:view and controller The components of the view are the 3 text fields. Each text field has an action command
incorporated in any ActionEvent it generates.
![Page 19: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/19.jpg)
Example: viewclass TextView extends JPanel implements
Observer {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.setActionCommand(“Hypotenuse”); …}…
![Page 20: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/20.jpg)
Example: view (cont.) update is invoked whenever the model changes state.
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));}
private final static int FIELD_SIZE = 16;private JTextField base;private JTextField height;private JTextField hypotenuse;
}
![Page 21: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/21.jpg)
Example: controller
It captures user input from the base and height text fields, and updates the model.
Because the controller and the view are very closely related, we make the controller class an inner class of TextView.
The controller will then have direct access to the view’s text field components.
The controller must be an ActionListener and must respond to ActionEvents generated by the text fields. It implements actionPerformed.
![Page 22: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/22.jpg)
Example: Controllerclass TVController implements ActionListener {
public TVController(RightTriangle model, TextView view) {
this.model = model; this.view = view; view.base.addActionListener(this); view.height.addActionListener(this);}public void actionPerformed (ActionEvent e) { JTextField tf = (JTextField)e.getSource(); try {
int i = Integer.parseInt(tf.getText());String which = e.getActionCommand();if (which.equals(“Base”)); model.setBase(i);else model.setHeight(i);
} catch (NumberFormatExeception ex) {view.update(model, null);
}}private TextView view;private RightTrangle model;
}
![Page 23: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/23.jpg)
Example
![Page 24: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/24.jpg)
View layout
We lay out components in a 2 3 grid, using a GridBagLayout layout manager.
A GridBagLayout layout manager uses a GridBagConstraints object to position each component.
![Page 25: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/25.jpg)
View layout (cont.)public TextView (RightTriangle model) {
super();setLayout(new GridBagLayout());GridBagConstraints constraints =
new GrideBagContraints();constraints.gridx = 0;constraints.gridy =
GridBagConstraints.RELATIVE;constraints.anchor =
GridBagConstrains.EAST;constraints.insets = new Insets(5,5,5,5);add(new Label(“Base”),constraints);add(new Label(“Height”),constraints); add(new Label(“Hypotenuse”),constraints);constraints.gridx = 1;base = new JTextField(FIELD_SIZE);base.setActionCommand(“Base”);add(base,constraints);
![Page 26: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/26.jpg)
View layout (cont.)height = new JTextField(FIELD_SIZE);height.setActionCommand(“Height”);add(height,constraints);
hypotenuse = new JTextField(FIELD_SIZE);hypotenuse.setEditable(false);add(hypotenuse,constraints);
model.addObserver(this);controller = new TVController(Model,
this);update(model,null);
}
![Page 27: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/27.jpg)
![Page 28: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/28.jpg)
![Page 29: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/29.jpg)
![Page 30: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/30.jpg)
![Page 31: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/31.jpg)
A graphic view
This shows a graphic rendition of the triangle without a controller.
The basic structure is the same as the previous view.
![Page 32: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/32.jpg)
A graphical view
JPanel is not just a container for other components, but also is useful as a blank canvas on which to draw.
We override the JPanel paintComponent method to draw.
The Graphics object provides several methods for drawing on components.
![Page 33: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/33.jpg)
![Page 34: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/34.jpg)
![Page 35: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/35.jpg)
View
A view does not need to be a part of a graphical interface.
Example: A view can log changes in the model’s state to a file.
![Page 36: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/36.jpg)
![Page 37: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/37.jpg)
![Page 38: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/38.jpg)
MVC and Swing
Swing components are structured along the Model-View-Controller pattern.
![Page 39: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/39.jpg)
Swing: model
Each Swing JComponent has an associated model object that is responsible for maintaining the component’s state.
![Page 40: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/40.jpg)
Swing: model (cont.)
ButtonModel:public boolean isPressed()
public boolean isEnabled()
public void setPressed (boolean b)
public void setEnabled (boolean b)
default class: DefaultButtonModel.
State information is maintained by a Document.
![Page 41: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/41.jpg)
Swing: UI delegate
Because the view and controller for a component are very closely related, they are combined into one object for many Swing components.
The component delegates the view and control responsibilities to its UI delegate.
The plugable look-and-feel package (javax.swing.plaf) contains an abstract delegate class for each Swing component.
Basic classes in javax.swing.plaf.basic can be used for building custom look-and-feel components.
![Page 42: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/42.jpg)
Swing: UI delegate
A standard JButton implementation consists of: a model (implements the interface
ButtonModel) a look-and-feel specific view element An element that responds to user input and
functions as a controller
![Page 43: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/43.jpg)
JButton MVC
![Page 44: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/44.jpg)
We’ve covered
The Model-View-Controller pattern. The standard Java library for
implementing the observes relation.
Swing components structured along the lines of MVC.
![Page 45: Chapter 19](https://reader036.vdocuments.net/reader036/viewer/2022081519/5681462a550346895db339b4/html5/thumbnails/45.jpg)
Glossary