• No results found

Object-Oriented Design Patterns part II and a short introduction to GUI. Slide 1

N/A
N/A
Protected

Academic year: 2021

Share "Object-Oriented Design Patterns part II and a short introduction to GUI. Slide 1"

Copied!
47
0
0

Loading.... (view fulltext now)

Full text

(1)

Slide 1

Object-Oriented Design Patterns part II

and a short introduction to GUI

(2)

Slide 2

Lesson Overview

Topics covered

(1) The Composite Design Pattern (2) The Adapter Design Pattern

(3) A short introduction to GUI components

(4) Event Handling Mecahnisms

(3)

Slide 3

The Composites Design Pattern

Intent

Compose objects into tree structures to represent part- whole hierarchies.

Composite lets clients treat individual objects and compositions of objects uniformly.

This is called recursive composition.

(4)

Slide 4

Composite Design Pattern (cont.)

Motivation

Graphics application like drawing editors let the user build complex diagrams out of simple components.

The user can group components to form larger

components, which in turn can be grouped to form still larger components.

A simple solution is to define classes for graphical

primitives such as Text and Lines plus other classes that

act as containers for these primitives. (bad idea, why?)

(5)

Slide 5

Composite Design Pattern (cont.)

Motivation

Code that uses these classes must treat primitives and container objects differentlyl, even if most of the time the user treats them identically.

Having to distinguish these objects makes the application more complex.

The Composite design pattern describes how to use

recursive composition so clients don't have to make this

distinction.

(6)

Slide 6

Composite Design Pattern – Motiviation (cont.)

The key is an abstract class that represents both primitives and containers.

For the graphic system, this class is Graphic: which declares

operations like Draw that are specific for graphical objects, and

also operations that all composite objects share, like operations

for accessing and manging its children.

(7)

Slide 7

Composite Design Pattern – Motiviation (cont.)

The Picture class allows to define aggregate Graphic objects.

Picture implements Draw to call the Draw method on its children, and it implements child-related operations accordingly.

Since Picture conforms to the Graphic interface, we can compose

Picture objects recursively:

(8)

Slide 8

Composite Design Pattern

Applicability

Use the Composite Pattern when

You want to represent part-whole hierarchies of objects.

You want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will

treat all objects in the composite structure uniformly.

(9)

Slide 9

Composite Design Pattern

Structure

(10)

Slide 10

Composite Design Pattern

Collaborations

Clients use the Component class interface to interact with objects in the composite structure.

If the recipient is a Leaf, then the request is handled directly.

If it is a Composite, then it usually forwards requests to its

child components, possibly performing additional operations

before and/or after forwarding

(11)

Slide 11

Composite Design Pattern

Consequences

Benefits:

Makes it easier to add new kinds of components – does not require change in the client code, and will also easily fit into existing structures.

Makes the clients simpler since they do not have to know if they are dealing with a leaf or a composite component –

simplifies client code.

Liabilities:

Can make the design overtly general – harder to restrict the

type of components of a composite.

(12)

Slide 12

Composite Design Pattern

Implementation Issues

Explicit Parent References: A composite object knows its

contained components, that is, its children. Should components maintain a reference to their parent component?

Answer: Depends on application, but having these references

supports the Chain of Responsibility pattern.

(13)

Slide 13

Composite Design Pattern

Implementation Issues (cont.)

Child Management : Where should the child management methods (add(), remove(), getChild()) be declared?

Option 1: In the Component class: Gives transparency, since all components can be treated the same. But it's not safe, since clients can try to do meaningless things to leaf

components at run-time.

Option 2: In the Composite class: Gives safety, since any

attempt to perform a child operation on a leaf component will be caught at compile-time. But we lose transparency, since now leaf and composite components have different

interfaces.

(14)

Slide 14

Composite Design Pattern

Implementation Issues (cont.)

Child Management : Transparent Vs. Safe:

(15)

Slide 15

Composite Design Pattern

Implementation Issues (cont.)

Component Management : Should Component maintain the list of components that will be used by a composite object? That is, should this list be an instance variable of Component rather than Composite?

Better to keep this part of Composite and avoid wasting the space in every leaf object.

Child Ordering: Is child ordering important?

Depends on application

(16)

Slide 16

Composite Design Pattern

Implementation Issues (cont.)

Who should delete components?

Not a problem in Java! The garbage collector will come to the rescue! In languages without garbage collection, its

usually best to make a Composite responsible for deleting its children.

What's the best data structure to store components?

Depends on application: a variety of data structures can be

used to store children including: linked-lists, trees, arrays

and hash-tables. Many times it isn't even necessary to use

general-purpose data structures at all.

(17)

Slide 17

Composite Example no. 1

Scenario:

A GUI system has window objects which can contain

various GUI components (widgets) such as, buttons and text areas.

A window can also contain widget container objects which can hold other widgets.

Solution 1:

Design all the widgets with different interfaces for

"updating" the screen?

(18)

Slide 18

Composite Example no. 1

We would then have to write a Window update() method as follows:

public class Window { Button[] buttons;

Menu[] menus;

TextArea[] textAreas;

WidgetContainer[] containers;

(19)

Slide 19

Composite Example no. 1

public void update() { //Class Window continued:

if (buttons != null)

for (int k = 0; k < buttons.length; k++) buttons[k].draw();

if (menus != null)

for (int k = 0; k < menus.length; k++) menus[k].refresh();

// Other widgets handled similarly.

if (containers != null)

for (int k = 0; k < containers.length; k++ ) containers[k].updateWidgets();

} ... } //end of class

(20)

Slide 20

Composite Example no. 1

Solution 1:

Looks particularly bad! - It violates the Open-Closed

Principle: If we want to add a new kind of widget, we have to modify the update() method of Window to handle it.

Solution 2:

We should always try to program to an interface, So, let's

make all widgets support the Widget interface, either by

being subclasses of a Widget class or implementing a Java

Widget interface.

(21)

Slide 21

Composite Example no. 1

Now our update() method becomes:

public class Window { Widget[] widgets;

WidgetContainer[] containers;

public void update() { if (widgets != null)

for (int k = 0; k < widgets.length; k++) widgets[k].update();

if (containers != null)

for (int k = 0; k < containers.length; k++ ) containers[k].updateWidgets();

} ... }// of class

(22)

Slide 22

Composite Example no. 1

Solution 2:

That looks better, but we are still distinguishing between widgets and widget containers

Solution 3: The Composite Pattern!

(23)

Slide 23

Composite Example no. 1

Now our update() method becomes:

public class Window {

Component[] components;

public void update() {

if (components != null)

for (int k = 0; k < components.length; k++) components[k].update();

}

}

(24)

Slide 24

The Java AWT Hierarchy (old version)

(25)

Slide 25

Java JFC and Swing

JFC - Java Foundation Classes: encompass a group of features for building graphical user interfaces (GUIs) and adding rich graphics functionality and interactivity to Java applications.

JFC contains the following (incomplete list):

(1) Swing GUI Components – Windows, Buttons, Checkboxes...

(2) Pluggable Look-and-Feel Support - Gives any program that uses Swing components a choice of look and feel. For example, the same program can use either the Java or the Windows look and feel.

(3)Java 2D API - Enables developers to easily incorporate high- quality 2D graphics, text, and images in applications and

applets.

(26)

Slide 26

Graphical HelloWorld Application

import javax.swing.*;

public class HelloWorldSwing {

public static void main(String[] args) {

//Schedule a job for the event-dispatching thread:

//creating and showing this application's GUI.

javax.swing.SwingUtilities.invokeLater(

new Runnable() {

public void run() {

createAndShowGUI();

} });

}

(27)

Slide 27

Graphical HelloWorld Application

private static void createAndShowGUI() {

//Make sure we have nice window decorations.

JFrame.setDefaultLookAndFeelDecorated(true);

//Create and set up the window.

JFrame frame = new JFrame("HelloWorldSwing");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Add the ubiquitous "Hello World" label.

JLabel label = new JLabel("Hello World");

frame.getContentPane().add(label);

//Display the window.

frame.pack();

frame.setVisible(true); }

(28)

Slide 28

Result?

The HelloWorldSwing example has only one top-level container, a JFrame - Implemented as an instance of the JFrame class.

The Jframe class is a window that, by default, has decorations such as a border, a title, and buttons for iconifying and closing the window.

Applications with a GUI typically use at least one frame.

All Swing components descend from the JComponent class,

except top level containers like JFrame.

(29)

Slide 29

Example 2

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

public class SwingApplication implements ActionListener {

private static String labelPrefix =

"Number of button clicks: ";

private int numClicks = 0;

final JLabel label = new Jlabel(

labelPrefix + "0 ");

//Specify the look and feel to use.

final static String LOOKANDFEEL = UIManager.getSystemLookAndFeelClassName();

(30)

Slide 30

Example 2 cont.

public Component createComponents() {

JButton button = new JButton("I'm a Swing button!");

button.setMnemonic(KeyEvent.VK_I);

button.addActionListener(this);

label.setLabelFor(button);

/* An easy way to put space between a top-level

container and its contents is to put the contents in a Jpanel that has an "empty" border.*/

JPanel pane = new JPanel(new GridLayout(0, 1));

pane.add(button);

pane.add(label);

pane.setBorder(BorderFactory.createEmptyBorder(

30,30,10,30));

return pane;

}

(31)

Slide 31

Example 2 cont.

//The Event handling mechanism in Java (more details in our next lesson)

public void actionPerformed(ActionEvent e) { numClicks++;

label.setText(labelPrefix + numClicks);

}

(32)

Slide 32

Example 2 cont.

private static void createAndShowGUI() {

//Make sure we have nice window decorations.

JFrame.setDefaultLookAndFeelDecorated(true);

//Create and set up the window.

JFrame frame = new JFrame("SwingApplication");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

SwingApplication app = new SwingApplication();

Component contents = app.createComponents();

frame.getContentPane().add(contents, BorderLayout.CENTER);

//Display the window.

frame.pack();

frame.setVisible(true);

}

(33)

Slide 33

Adding Swing Components into a GUI application

Like most GUIs, the SwingApplication GUI contains a button and a label. Here's the code that initializes the button:

...// where instance variables are declared:

private static String labelPrefix = "Number of button clicks: ";

private int numClicks = 0;

...// in GUI initialization code:

final JLabel label = new JLabel(labelPrefix + "0 ");

...

label.setLabelFor(button);

...// in the event handler for button clicks:

label.setText(labelPrefix + numClicks);

(34)

Slide 34

Adding Swing Components into a GUI application

Now that you know how to set up buttons, you also know much of what's needed to set up check boxes and radio buttons, as they all inherit from the AbstractButton class.

Check boxes are similar to radio buttons, but by convention their selection models are different. Any number of check boxes in a group--none, some, or all--can be selected.

On the other hand, by convention only one button can be selected

from a group of radio buttons.

(35)

Slide 35

Button Examples

(36)

Slide 36

Adding Swing Components into a GUI application

SwingApplication groups its label and button in a container (a

JPanel) before adding the components to the frame. Here's the code that initializes the container:

JPanel panel = new JPanel(new GridLayout(0,1));

panel.add(button);

panel.add(label);

panel.setBorder(BorderFactory.createEmptyBorder(...));

(37)

Slide 37

Handling Events

Every time the user types a character or pushes a mouse button, an event occurs.

Any object can be notified of the event.

All the object has to do is implement the appropriate interface and be registered as an event listener on the appropriate event source .

SwingApplication class implements an event handler for button

clicks (action events).

(38)

Slide 38

Handling Events

The event handling code:

public class SwingApplication implements ActionListener { ...

JButton button = new JButton("I'm a Swing button!");

button.addActionListener(this);

....

public void actionPerformed(ActionEvent e) { numClicks++;

label.setText(labelPrefix + numClicks);

}

}

(39)

Slide 39

Handling Events

Every event handler requires three pieces of code:

(1) In the declaration for the event handler class, one line of code specifies that the class either implements a listener interface or extends a class that implements a listener interface. For example:

public class MyClass implements ActionListener { (2) Another line of code registers an instance of the event

handler class as a listener on one or more components. For example:

someComponent.addActionListener(instanceOfMyClass);

(40)

Slide 40

Handling Events

Every event handler requires three pieces of code: (cont.)

(3) The event handler class has code that implements the methods in the listener interface. For example:

public void actionPerformed(ActionEvent e) { ...//code that reacts to the action...

}

(41)

Slide 41

Handling Events

In general, to detect when the user clicks an onscreen button (or does the keyboard equivalent), a program must have an object

that implements the ActionListener interface.

The program must register this object as an action listener on the button (the event source), using the addActionListener

method.

When the user clicks the onscreen button, the button fires an action event.

This results in the invocation of the action listener's

actionPerformed method (the only method in the ActionListener

interface).

(42)

Slide 42

Handling Events

The single argument to the method is an ActionEvent object that

gives information about the event and its source.

(43)

Slide 43

Event Types

Swing components can generate many kinds of events. Here are

some examples:

(44)

Slide 44

Swing Visual Components

(45)

Slide 45

Swing Visual Components

(46)

Slide 46

Swing Visual Components

(47)

Slide 47

Swing Visual Components

References

Related documents

According to our findings of this study and regarding beneficial results of reflexotherapy on vital sign following angiography, improvement in some of vital

compass.init init (); (); // start accelerometer and magnetometer // start accelerometer and

clinical information models in the context of secondary use of Electronic Medical Records (EMR) data.. •   The Office of the National

This article charts the writing process for the three editions of the Australian Media Studies textbook Media: new ways and meanings, and places the book

public class DialogFragment extends android.app.DialogFragment { private DialogFragmentListener

• Event handler A method that responds to an event; part of the event listener that is invoked by the event source object. • Firing an event An event source generates an

class that is interested in processing an action event implements this interface, and the object created with that class is registered with a component, using the

For event handling interfaces with more than one method, Java provides a corresponding class (adapter class) that already implements all the methods in the interface for you.. All