Design Patterns and Graphical User Interfaces

advertisement
Design Patterns and
Graphical User Interfaces
Horstmann 5-5.4.1, 5.4.3-5.7
Design patterns
• Design Patterns
•
•
•
•
•
Iterator
Model-View-Controller and Observer
Strategy
Composite
Decorator
Design patterns
• For each design pattern
– Prototypical example
– Context, problem
– Solution, decoupling/interface
– UML diagram
• Patterns
– Iterator, observer, strategy, composite,
decorator
Design patterns
• Design Patterns
• Iterator
•
•
•
•
Model-View-Controller and Observer
Strategy
Composite
Decorator
Example:
accessing elements in an ArrayList
ArrayList<String> filmList = new ArrayList<String>();
filmList.add(”E.T.”); filmList.add(”Gran Torino”);
• Printing all elements
for (String film : filmList) System.out.println(film);
• Printing all elements using iterator
Iterator<String> iter = filmList.iterator();
while (iter.hasNext()) System.out.println(iter.next());
• Printing all elements ”manually”
for (int i=0; i< filmList.size(); i++)
System.out.println(filmList.get(i));
Example:
Accessing elements in arbitrary container
public Class FilmCatalogue {
private String[] films = {”Dogville”,”Chinatown”};
public String get(int i) {return films[i];}
public int size() {return films.length;}
}
• Uses encapsulation: YES
• Fully decoupled: NO
– Only ”manual” printing of elements in a FilmCatalogue object possible
– very inefficient if array representation changed to linked lists
Better: decoupling with iterator:
public class FilmCatalogue implements Iterable<String> {
public Iterator<String> iterator() {
return new Iterator<String>() {
private int position = 0;
public boolean hasNext() {return position<films.length;}
public String next() {
if (hasNext()) return films[position++];
else return null;
}
... }; } ... }
Example:
accessing elements in iterable FilmCatalogue
FilmCatalogue filmList = new ArrayList<String>();
filmList.add(”E.T.”); filmList.add(”Gran Torino”);
FilmCatalogue filmList = new FilmCatalogue();
• Printing all elements
for (String film : filmList) System.out.println(film);
• Printing all elements using iterator
Iterator<String> iter = filmList.iterator();
while (iter.hasNext()) System.out.println(iter.next());
• Printing all elements ”manually”
for (int i=0; i< filmList.size(); i++)
System.out.println(filmList.get(i));
Iterator Pattern
Context
• An aggregate object contains element objects
• Clients need access to the element objects
• The aggregate object should not expose its internal
structure
• Multiple clients may want independent access
Solution
• Define an iterator that fetches one element at a time
• Each iterator object keeps track of the position of the
next element
• If there are several aggregate/iterator variations, it is
best if the aggregate and iterator classes realize
common interface types.
Iterator Pattern
Iterator Pattern
EXAMPLE
Iterable
<String>
Iterator
<String>
iterator()
next()
! hasNext()
next()
FilmCatalogue
anonymous
Library myLib = new Library(...);
QUIZ
Which of the code pieces
obey the iterator pattern in
the UML diagram ?
1.None
2.A only
3.B only
4.C only
5.D only
6.Two of A,B,C,D
7.Three of A,B,C,D
8.All of A,B,C,D
9.I don’t know
A
for (Book text : myLib)
System.out.println(text);
B
Iterator<Book> iter = myLib.iterator();
while (iter.hasNext())
System.out.println(iter.next());
C
Book[] list = myLib.getBooks();
for (int i=0; i< list.length; i++)
System.out.println(list[i]);
D
for (Book text : myLib.getBooks())
System.out.println(text);
Design patterns
• Design Patterns
• Iterator
• Model-View-Controller and
Observer
• Strategy
• Composite
• Decorator
Model/View/Controller Extra/changed
view
transparent to
content
Model/View/Controller
• Model: data structure, no visual representation
• Views: visual representations
• Controllers: user interaction
• Views/controllers update model
• Model tells views that data has changed
• Views redraw themselves
Model/View/Controller
Button / Listener
• recall old example
helloButton.addActionListener(new
ActionListener() {
public void actionPerformed(ActionEvent event) {
textField.setText("Hello, World");
}
}
);
Observer Pattern
• Model notifies views when something interesting happens
• Button notifies action listeners when something interesting
happens
• Views attach themselves to model in order to be notified
• Action listeners attach themselves to button in order to be
notified
• Generalize: Observers attach themselves to subject
Observer Pattern
Observer Pattern
JButton
ActionListener
addActionListener()
actionPerformed()
anonymous
Display Components
Button Components
QUIZ
Which interpretations
are reasonable?
1.None
2.a
3.b
4.c
5.a+b
6.a+c
7.b+c
8.a+b+c
9.I dont’t know
a) MVC:
Frame is Model
Display Components are Views
Buttons are Controllers
b) MVC:
Model is not visible, but contains a number
Display Components are Views
Listeners attached to Buttons are Controllers
c) Observer:
A Button is a Subject
A Listener attached to a button is an Observer
Design patterns
• Design Patterns
• Iterator
• Model-View-Controller and Observer
• Strategy
• Composite
• Decorator
GUI: components and containers
textfield
component
3 button
components
label
component
frame container
with 5 components (textfield, 3 buttons, label)
Layout Managers
•
•
•
•
•
User interfaces made up of components
Components placed in containers
Container needs to arrange components
Swing doesn't use hard-coded pixel coordinates
Advantages:
– Can switch "look and feel"
– Can internationalize strings
• Layout manager controls arrangement
Layout Managers
Layout Managers
Example
JPanel decDisplay = new JPanel();
final JTextField digits = new JTextField(“98",15);
decDisplay.add(new JLabel("Decimal:"));
decDisplay.add(digits);
JPanel Default :
FlowLayout
JPanel display = new JPanel();
display.setLayout(new BorderLayout());
display.add(decDisplay, BorderLayout.NORTH);
display.add(binDisplay, BorderLayout.SOUTH);
BorderLayout
Example
JPanel keyboard = new JPanel();
keyboard.setLayout(new GridLayout(2,2));
keyboard.add(new JButton("0"));
keyboard.add(new JButton("inc"));
keyboard.add(new JButton("1"));
keyboard.add(new JButton("dec"));
JFrame f = new JFrame();
f.add(display,BorderLayout.NORTH);
f.add(keyboard,BorderLayout.CENTER);
GridLayout
JFrame Default :
BorderLayout
Strategy Pattern
• Pluggable strategy for layout management
• Layout manager object responsible for
executing concrete strategy
• Generalizes to Strategy Design Pattern
• Other manifestation: Comparators
Comparator comp = new CountryComparatorByName();
Collections.sort(countries, comp);
Strategy Pattern
Context
• A class can benefit from different variants for an
algorithm
• Clients sometimes want to replace standard algorithms
with custom versions
Solution
• Define an interface type that is an abstraction for the
algorithm
• Actual strategy classes realize this interface type.
• Clients can supply strategy objects
• Whenever the algorithm needs to be executed, the
context class calls the appropriate methods of the
strategy object
Strategy Pattern
Strategy Pattern
Comparator
Collections
Compare()
anonymous
Strategy Pattern
Container
LayoutManager
layoutContainer()
BorderLayout
QUIZ
Which versions of Graph
class use strategy pattern?
1. None
2. A
3. B
4. A,B
5.I don’t know
public class Graph {
private Function f = new Logarithm();
A
public draw()
{ plot(1,f.evaluate(1)); … }
}
public class Graph {
private Function f;
public Graph(Function fun) { f=fun; }
B
public draw()
{ plot(1,f.evaluate(1)); … }
}
Design patterns
•
•
•
•
Design Patterns
Iterator
Model-View-Controller and Observer
Strategy
• Composite
• Decorator
Containers and Components
• Containers collect GUI components
• Sometimes, want to add a container to another container
• Container should be a Component
• Composite design pattern
• Composite method typically invoke component methods
• E.g. Container.getPreferredSize invokes
getPreferredSize of components
Composite Pattern
Context
• Primitive objects can be combined to composite objects
• Clients treat a composite object as a primitive object
Solution
• Define an interface type that is an abstraction for the primitive
objects
• Composite object collects primitive objects
• Composite and primitive classes implement same interface type.
• When implementing a method from the interface type, the composite
class applies the method to its primitive objects and combines the
results
Composite Pattern
Composite Pattern
Component
JButton
getPreferredSize()
JPanel
QUIZ
Does UML and code for
paint methods realize
composite design pattern?
1.Yes, both UML and code
2.Only UML
3.Only code
4.Neither UML nor code
5.I don’t know
class Rectangle:
public void paint(Graphics2D g) {
g.draw(. . .);
}
class Composite:
private ArrayList<Rectangle> cubes;
public void paint(Graphics2D g) {
for (Rectangle r: cubes)
r.paint(g);
}
Design patterns
•
•
•
•
•
Design Patterns
Iterator
Model-View-Controller and Observer
Strategy
Composite
• Decorator
Scroll Bars
• Scroll bars can be attached to components
• Approach #1: Component class can turn on scroll bars
• Approach #2: Scroll bars can surround component
JScrollPane pane = new JScrollPane(component);
• Swing uses approach #2
• JScrollPane is again a component
Decorator Pattern
Context
• Component objects can be decorated (visually or behaviorally
enhanced)
• The decorated object can be used in the same way as the
undecorated object
• The component class does not want to take on the responsibility of
the decoration
• There may be an open-ended set of possible decorations
Solution
• Define an interface type that is an abstraction for the component
• Concrete component classes realize this interface type.
• Decorator classes also realize this interface type.
• A decorator object manages the component object that it decorates
• When implementing a method from the component interface type,
the decorator class applies the method to the decorated component
and combines the result with the effect of the decoration.
Decorator Pattern
Decorator Pattern
JComponent
JTextArea
paintComponent()
JScrollPane
QUIZ
Does UML and code for
paint methods realize
decorator design pattern?
1.Yes, both UML and code
2.Only UML
3.Only code
4.Neither UML nor code
5.I don’t know
class Rectangle:
public void paint(Graphics2D g) {
g.draw(. . .);
}
class Decor:
private Cubism cube;
public void paint(Graphics2D g) {
g.draw(new Rectangle2D(. . .));
g.draw(... cube ...);
}
Download