580 likes | 604 Views
Learn about the Model-View-Controller paradigm in Java GUI development. Explore examples from Arnow and Weiss on object-oriented design and creating a counter applet using Java's Abstract Window Toolkit. See how to separate interface design from application logic for better applet development.
E N D
The Model-View-Controller Paradigm Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
A Counter Applet • Two buttons • Value field Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The CounterApplet Class import java.applet.*; import java.awt.*; import java.awt.event.*; public class CounterApplet extends Applet implements ActionListener { public void init() {…} public void actionPerformed(ActionEvent e) {…} Button incButton, decButton; // Instance variables TextField valField; } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The init Method public void init() { incButton = new Button("+"); // Create Controls decButton = new Button("-"); valField = new TextField(); valField.setText("0"); Panel p = new Panel(); // Lay them out p.setLayout(new BorderLayout()); p.add(incButton, "North"); p.add(decButton, "South"); add(p); add(valField); // Register as listener incButton.addActionListener(this); decButton.addActionListener(this); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The actionPerformed Method public void actionPerformed(ActionEvent e) { // Retrieve text field int val = Integer.parseInt(valField.getText()); if (e.getSource() == incButton) val++; else val--; // Update text field valField.setText(Integer.toString(val)); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
An Unexpected Benefit (Bug?) • Can directly modify the counter value through the TextField • We’re using the contents of the TextField as our counter value. We’ll call it a feature Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Concern I • CounterApplet is modeling too many things: • General behavior of an applet (inherited from Applet) • GUI of our particular application • Display of the two buttons and the text field • Role as listener to the two buttons • Behavior of an up/down counter Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Concern II • The counter logic is all over the place • Initialization is in applet’s init method • Maintenance logic is in actionPerformed • What if we wanted a bounded counter? • No real counter value • "maintained" indirectly as a string in a text field • Makes it difficult to understand and maintain Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Concern III • What if we want • a Scrollbar rather than a pair of Buttons • a Label rather than a TextField? • Requires changing/moving the "counter" logic Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Good Interface Design • Separate interface from application: • Interface: should not affect application logic • Application: should not know about interface. Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Revising the Counter Applet • Have a Counter class • Encapsulate application logic of up/down counter • The CounterApplet class then uses the Counter class. Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The Counter Class public class Counter { public Counter(int max) {this.max = max;} public void reset() {val = 0;} public int getVal() {return val;} public void setVal(int val) { if (val >= 0 && val <= max) this.val = val; } public void inc() {if (val < max) val++;} public void dec() {if (val > 0) val--;} private int max, val=0; // Instance variables } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The CounterApplet Class import java.applet.*; import java.awt.*; import java.awt.event.*; public class CounterApplet extends Applet implements ActionListener { public void init() {…} public void actionPerformed(ActionEvent e) {…} Button incButton, decButton; // Instance variables TextField valField; Counter ctr; } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The init Method public void init() { ctr = new Counter(10); incButton = new Button("+"); decButton = new Button("-"); valField = new TextField(); valField.setText(Integer.toString(ctr.getVal())); Panel p = new Panel(); p.setLayout(new BorderLayout()); p.add(incButton, "North"); p.add(decButton, "South"); add(p); add(valField); incButton.addActionListener(this); decButton.addActionListener(this); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The actionPerformed Method public void actionPerformed(ActionEvent e) { if (e.getSource() == incButton) ctr.inc(); else ctr.dec(); valField.setText(Integer.toString(ctr.getVal)); } • The event handler for the Button invokes the appropriate counter method and updates the TextField. • We no longer use the TextField for the counter value. Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Better Applet, but... • actionPerformed still responsible for updating the TextField. • What if we decide to change the TextField to a • Label? • A Scrollbar • A gauge? Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
One Possible Approach • We could isolate the display update logic into a helper method that can be called from anywhere. • However, the CounterApplet still has to know WHEN the Counter has changed. • We will try something a bit different. Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Model-View-Controller (MVC) • Separates application, user input, and display logics. • Makes for an exceptionally clean design • Minimal coupling between interface and application Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Model • Application • Interface-independent • Examples • Spreadsheet data • Counter class Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
View • Display • Responsible for maintaining an updated view of the model • Must be notified of changes to the model. • Examples • graph, matrix • TextField update Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Controller • Input • Often initiates changes to the model. • Examples • keyboard, mouse • actionPerformed Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Document-View • Often easier to combine view and controller. • Sometimes known as document-view. Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Model as Observed • Must notify view when changes happen • Model must know: • Who is the view? • How to notify the view of the change? Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Symmetric with Event Handling View notification • Who is the view? • How to notify view? Event Handling • Who is the listener? • How to notify listener? Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
View as Observer • Who is the view? • View registers with the model • How to notify view that change happened? • View implements an "observer" interface Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The Symmetry Continues View notification • View registers with model • View implements observer interface Event Handling • Listener registers with event source • Listener implements listener interface Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The Counter Applet Using MVC • class Counter— Model • class CounterApplet — View/Controller • interface CounterObserver — observer interface • developed for our applet— not predefined Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
CounterObserver Interface • Implemented by view to ‘listen’ for model changes • Single method with the Counter as a parameter. • When invoked allows view to be updated. interface CounterObserver { public void counterHasChanged(Counter ctr); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Counter Class Overview • Same basic functionality, plus… • Maintains a CounterObserver as part of its state. • Provides observer registration method • registerAsObserver • Notifies observer of changes • Relies upon observer implementing CounterObserver Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Counter Class public class Counter { public Counter(int max) {this.max = max;} public void reset() {val = 0;} public int getVal() {return val;} // Manipulator methods- // must notify observer the model has changed public void setVal(int val) {…} public void inc() {...} public void dec() {...} // Observer-related methods public void registerAsObserver(CounterObserver observer){…} private void notifyObserver() {...} private int max, val=0; CounterObserver observer; } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Counter’s Manipulator Methods public void setVal(int val) { if (val >= 0 && val <= max) this.val = val; notifyObserver(); } public void inc() { if (val < max) val++; notifyObserver(); } public void dec() { if (val > 0) val--; notifyObserver(); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Counter’s Observer-Related Methods public void registerAsObserver(CounterObserver observer) { this.observer = observer; notifyObserver(); // Allow initial display } private void notifyObserver() { observer.counterHasChanged(this); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
CounterApplet Class Overview • Implements CounterObserver interface (view) • Registers with Counter during initialization (view) • Event-handlers invoke Counter methods but do not update view. (controller) • Updates TextField when counterHasChanged method is invoked. (view) Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
CounterApplet Class import java.applet.*; import java.awt.*; import java.awt.event.*; public class CounterApplet extends Applet implements ActionListener, CounterObserver { public void init() {…} public void actionPerformed(ActionEvent e) {…} public void counterHasChanged(Counter ctr) {…} Button incButton, decButton; TextField valField; Counter ctr; } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The init Method public void init() { incButton = new Button("+"); decButton = new Button("-"); valField = new TextField(); Panel p = new Panel(); p.setLayout(new BorderLayout()); p.add(incButton, "North"); p.add(decButton, "South"); add(p); add(valField); incButton.addActionListener(this); decButton.addActionListener(this); ctr = new Counter(10); ctr.registerAsObserver(this); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The Event-Handling Methods public void actionPerformed(ActionEvent e) { if (e.getSource() == incButton) ctr.inc(); else ctr.dec(); } • The event handler simply initiates model changes • NOT responsible for the display! Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The counterHasChanged Method public void counterHasChanged(Counter ctr) { valField.setText(Integer.toString(ctrVal)); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Now Let’s Have Some Fun! • We’ve shown you the basics of MVC • We’ve also claimed it results in a clean design • Model knows nothing of controller/view’s workings • All this leads to some very unexpected capabilities! Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Counters... • Two pairs of synchronized counters: • East/West • North/South Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
… Logs, ... • A logging facility in synch with the counters Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
… and Alarms • An alarm panel keeping track of the counter values Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Class Overview • Counter class: a model • same basic functionality, but ... • now allows multiple observers • CounterPanel class: a view and controller • creates our familiar counter GUI • observes the counter • similar structure to our previous CounterApplet class Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Class Overview (II) • CounterLogger: a view • prints out counter changes to System.out • observes the counter • maintains counter name • CounterAlarmPanel: a view • observes multiple counters • indicates movement past error threshold Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Class Overview (III) • CounterApplet • creates the various interface components • sits back and let’s them do all the work • CounterObserver interface • same as before Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
Counter Class import java.util.*; public class Counter { public Counter(int max) { this.max = max; observers = new Vector(); } public void reset() { /*Same as before*/ } public int getVal() { /*Same as before*/ } public void setVal(int val) { /*Same as before*/ } public void inc() { /*Same as before*/ } public void dec() { /*Same as before*/ } public void registerAsObserver(CounterObserver observer){…} private void notifyObservers() {…} private int max, val=0; Vector observers; // Allows multiple observers } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The registerAsObserver Method • observers are added to the Vector public void registerAsObserver(CounterObserver observer) { observers.addElement(observer); observer.counterHasChanged(this); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
The notifyObservers Method • Notification involves enumerating through the Vector and notifying each observer private void notifyObservers() { Enumeration enum = observers.elements(); while (enum.hasMoreElements()) { CounterObserver observer = (CounterObserver)enum.nextElement(); observer.counterHasChanged(this); } } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
CounterLogger Class class CounterLogger implements CounterObserver { public CounterLogger(Counter ctr, String counterName) { this.counterName = counterName; ctr.registerAsObserver(this); // Observes counter } public void counterHasChanged(Counter ctr) { System.out.println(counterName + " changed to " + ctr.getVal()); } private String counterName; // For id purposes } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
CounterPanel Class import java.applet.*; import java.awt.*; import java.awt.event.*; public class CounterPanel extends Panel implements ActionListener, CounterObserver { public CounterPanel(Counter ctr) {…} public void actionPerformed(ActionEvent e) {…} public void counterHasChanged(Counter ctr) {…} Button incButton, decButton; TextField valField; Counter ctr; } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit
CounterPanel Constructor public CounterPanel(Counter ctr) { incButton = new Button("+"); decButton = new Button("-"); valField = new TextField(); Panel p = new Panel(); p.setLayout(new BorderLayout()); p.add(incButton, "North"); p.add(decButton, "South"); add(p); add(valField); incButton.addActionListener(this); decButton.addActionListener(this); this.ctr = ctr; ctr.registerAsObserver(this); } Arnow and Weiss: Objects At Their Best— Java's Abstract Window Toolkit