unit 15: component programming and graphical user interface h component programming h listening to...

Post on 19-Dec-2015

244 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Unit 15: Component programming Unit 15: Component programming and Graphical User Interfaceand Graphical User Interface

Component programmingListening to eventsGUI componentsContainersLayout ManagersEvent Handling In GUI componentsInner and Anonymous Classes

basic programming

concepts

object oriented programming

topics in computer science

syllabus

2unit 15

Component ProgrammingComponent Programming

Component programming facilitates reuse of code

Developing an application becomes like building something with LEGO blocks: there are a lot of software components (blocks) and we combine them together into an application

3unit 15

ComponentsComponents

A component is a software element

It is an object in the regular OOP sense

It has some additional features:• methods and properties like a regular object• graphical view, describing the way the properties

are visualized• events by which it can communicate with other

components

4unit 15

EventsEvents

Components communicate via events

If component A wants to tell component B that something has happened to it, it fires an event aimed at component B

The event is an object that encapsulates the information that A wants to pass to B

There can be many types of events for different types of information - the type of the event is its class

5unit 15

EventsEvents For each type of event there should be:

• a suitable event class derived from java.util.EventObject• an interface for listening to events of this type derived from

java.util.EventListener

A component that is the source of some event (observable object) maintains a list of registered listeners, and notifies them when the event occurs

The component which responds to events (a listener) should implement the listening interface

The observable has a pair of methods for adding and removing listeners; the listener calls the add/remove methods

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

alarmActivated (AlramEvent e)

instance of

InterestedClassA implements AlarmListener

collection ofAlarmListeners

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

alarmActivated (AlramEvent e)

instance of

AlarmClock

instance of

InterestedClassA implements AlarmListener

collection ofAlarmListeners

InterestedClassA implements AlarmListener { // ... someMethod(AlarmClock a) { a.addAlarmListener(this); } // … void alarmActivated(AlarmEvent e) { // do something when an alarm occurs }}

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

alarmActivated (AlramEvent e)

instance of

AlarmClock

instance of

InterestedClassA implements AlarmListener

collection ofAlarmListeners

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

alarmActivated (AlramEvent e)

instance of

AlarmClock

instance of

InterestedClassA implements AlarmListener

collection ofAlarmListeners

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

alarmActivated (AlramEvent e)

instance of

AlarmClock

collection ofAlarmListeners

instance of

InterestedClassB implements AlarmListener

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

alarmActivated (AlramEvent e)

instance of

AlarmClock

collection ofAlarmListeners

instance of

InterestedClassB implements AlarmListener

InterestedClassB implements AlarmListener { // ... aMethodInThisClass() { AlarmClock a = AlarmUtilities.getAlarmClock(); a.addAlarmListener(this); } // ... void alarmActivated(AlarmEvent e) { // do what needs to be done with the alarm }}

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

alarmActivated (AlramEvent e)

instance of

AlarmClock

collection ofAlarmListeners

instance of

InterestedClassB implements AlarmListener

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

alarmActivated (AlramEvent e)

instance of

AlarmClock

collection ofAlarmListeners

instance of

InterestedClassB implements AlarmListener

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

Alarm Event

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

Alarm Eventclass AlarmClock { //... void notifyListeners(AlarmEvent e) { for each AlarmListener l in collection: l.alarmActivated(e); } //..}

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

Alarm Eventclass AlarmClock { //... void notifyListeners(AlarmEvent e) { for each AlarmListener l in collection: l.alarmActivated(e); } //..} alarmActivated()

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

Alarm Eventclass AlarmClock { //... void notifyListeners(AlarmEvent e) { for each AlarmListener l in collection: l.alarmActivated(e); } //..}

InterestedClassA implements AlarmListener { // ... someMethod(AlarmClock a) { a.addAlarmListener(this); } // … void alarmActivated(AlarmEvent e) { // do something when an alarm occurs }}

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

Alarm Eventclass AlarmClock { //... void notifyListeners(AlarmEvent e) { for each AlarmListener l in collection: l.alarmActivated(e); } //..}

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

Alarm Eventclass AlarmClock { //... void notifyListeners(AlarmEvent e) { for each AlarmListener l in collection: l.alarmActivated(e); } //..} alarmActivated()

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

Alarm Eventclass AlarmClock { //... void notifyListeners(AlarmEvent e) { for each AlarmListener l in collection: l.alarmActivated(e); } //..} alarmActivated()

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

Alarm Eventclass AlarmClock { //... void notifyListeners(AlarmEvent e) { for each AlarmListener l in collection: l.alarmActivated(e); } //..} alarmActivated()

addAlarmListener (AlarmListener l)

removeAlarmListener (AlarmListener l)

instance of

AlarmClock

collection ofAlarmListeners

26unit 15

Example: Alarm ClockExample: Alarm Clock

// A listener interface for receiving alarm events// from a clockpublic interface AlarmClockListenerAlarmClockListener { public void alarmActivated(AlarmEvent e);}

// Encapsulator for information on the alarm eventpublic class AlarmEventAlarmEvent { private AlarmClock eventSource; private Clock alarmTime; public AlarmEvent(AlarmClock source, Clock alarmTime) { //... }}

27unit 15

Example: Alarm ClockExample: Alarm Clock

public class AlarmClockAlarmClock extends Clock { private Clock alarmTime; private Vector listeners;

public void secondElapsed() { super.secondElapsed(); if (alarmTimeReached()) { notifyListeners(); } } // returns true if alarm time has been reached private boolean alarmTimeReached() { return alarmTime.equals(this); // Clock comparison }

28unit 15

Adding and Removing Interested ListenersAdding and Removing Interested Listeners

// Adds the specified alarm listener to receive alarm // events from this alarm clock. // @param listener the alarm listener public void addAlarmClockListener(AlarmClockListener listener) { listeners.addElement(listener); } // Removes the specified alarm listener

public void removeAlarmClockListener(AlarmClockListener listener)

{ listeners.removeElement(listener); }

29unit 15

Notifying ListenersNotifying Listeners

// Notifies all alarm listeners of an alarm event private void notifyListeners() { AlarmEvent event = new AlarmEvent(this, alarmTime); for (int i = 0; i < listeners.size(); i++) { AlarmClockListener listener = (AlarmClockListener)listeners.elementAt(i); listener.alarmActivated(event); } }}

30unit 15

Example: Alarm Clock ListenerExample: Alarm Clock Listener

public class InterestedListenerA InterestedListenerA implements AlarmClockListener {

// instance variables...

public InterestedListenerA(…) { // ... }

public void alarmActivated(AlarmEvent event) { System.out.println(“Wake me up before you go go”); }

}

31unit 15

Using AlarmClockUsing AlarmClock

public class test {

public static void main(String[] args) { InterestedListenerA IL = new InterestedListenerA();

AlarmClock alarmTime = new AlarmClock(0,0,1);alarmTime.addAlarmClockListener(IL);System.out.print("+1 second is passing: ");alarmTime.secondElapsed();System.out.print("+1 second is passing:");alarmTime.secondElapsed();

}}

public addXXXListener (XXXListener l)public removeXXXListener (XXXListener l)private notifyObservers()

...

class Observable

collection ofXXXListeners

public XXXHappened (XXXEvent e)

inteface XXXListener

public XXXHappened (XXXEvent e)...

class Observer implements XXXListener

Example: GUI componentsExample: GUI components

Button

B

A

addActionListener()Remember to notify:

When pressed.

removeActionListener()

Please let me

know when you

are pressed

actionPerformed()

OK

Please let me

know when you

are pressed

actionPerformed()

34unit 15

Button example: listening interfaceButton example: listening interface

A Button component fires an ActionEvent when it is pressed

Components that are interested in reacting to these events should ask the button to be notified of these events

In order to be notified of these events an object should implement the interface ActionListener

The interface ActionListener defines a method called actionPerformed(); this method will be used for notifying the object about the event

35unit 15

Button example: listenersButton example: listeners

If an object A wants to be notified about events of pressing the Button, it should ask the button to register it for receiving these events

It does so by calling the addActionListener() method from the Button, passing a reference to itself as a parameter

The Button keeps a list of references of type ActionListener, to objects that wish to listen to it

When its addActionListener() method its called, it adds the reference to the ActionListener that was passed to the list of listeners

36unit 15

Button example: listenersButton example: listeners

Similarly, an object can remove itself from listening to the Button by calling its removeActionListener() method

When the button is pressed, it creates a new ActionEvent object that encapsulates the information about the press; it then goes over the list of its listeners, and calls the method actionPermored() for each of its listeners with the new event as an argument

37unit 15

GUI with AWT & SwingGUI with AWT & Swing

Originally Java came with the very basic AWT (Abstract Window Toolkit)

Swing is a much richer API for GUI, which inherits many of the AWT features

38unit 15

Some AWT componentsSome AWT components

Button:

TextField:

Label:

Scrollbar:

Choice:

Frame:

39unit 15

The component classThe component class

Component

TextComponentButton

All components are derived from the class java.awt.Component

TextFieldTextArea

...

40unit 15

The Component ClassThe Component Class

Class component defines the properties common to all GUI components: location, size, background color, foreground color, visibility, ...

public Dimension getSize()

public void setSize(Dimension d)

public void setSize(int x, int y)

public Point getLocation()

public void setLocation(Point p)

public void setLocation(int x, int y)

public Color getBackground()

public void setBackground(Color c)

...

41unit 15

The Container ClassThe Container Class

Container is a subclass of Component that is a superclass of all Components that can contain other components

It adds to Component the functionality of adding/removing components

public void add(Component c)

public void remove(Component c)

public Component[] getComponents()

public int getComponentCount()

...

42unit 15

Frame: Window ContainerFrame: Window Container

A frame is a container that is free standing and can be positioned anywhere on the screen

Frames give us the ability to do graphics and GUIs through applications

Because a frame is a free standing window, it must address window events

43unit 15

Example: Opening a FrameExample: Opening a Frame

import java.awt.*;

// A sample program that opens a yellow frame

class FrameExampleFrameExample {

public static void main(String[] args) {

Frame frame = new Frame(“Example”);

frame.setSize(1000,600);

frame.setBackground(Color.yellow);

frame.setVisible(true);

}

}

44unit 15

Opening a Frame: version IIOpening a Frame: version II

// A sample program that opens a yellow frame

class FrameExampleFrameExample extends Frame {

public FrameExample () { super(“Example”); setSize(1000,600); setBackground(Color.yellow); }

public static void main(String[] args) { new FrameExample().setVisible(true); }}

A better code would be to define a new type of Frame with the required properties:

45unit 15

GUI ComponentsGUI Components

There are various AWT/Swing GUI components that we can incorporate into our window container:

• labels (including images)

• text fields and text areas

• buttons

• check boxes

• radio buttons

• menus

• and many more…

46unit 15

ButtonsButtons

GUI buttons fall into various categories:

• push button – a generic button that initiates some action• check box – a button that can be toggled on or off• radio buttons – a set of buttons that provide a set of mutually

exclusive options

Radio buttons must work as a group - only one can be toggled on at a time; radio buttons are grouped using the ButtonGroup class

Push buttons and radio buttons generate action events when pushed or toggled; Check boxes generate item state changed events when toggled

47unit 15

Example: Adding Button ComponentExample: Adding Button Component

// A sample program that opens a frame with a button class FrameExampleFrameExample extends Frame {

public static void main(String[] args) { new FrameExample().setVisible(true); } public FrameExample () { super(“Example”); setSize(1000,600); Button okButton = new Button(“OK”); okButton.setSize(80,20); okButton.setLocation(160,200); add(okButton); }}

48unit 15

Problem: LayoutProblem: Layout

When the window is resized, the button’s position and size remains fixed

We would like an automatic and flexible mechanism for repositioning components in a container, and resizing them if needed

49unit 15

Where and how are the components addedWhere and how are the components added??

There are two ways to layout components on a container: • Set the exact size and location of every component• Use a LayoutManager

Every container has its own LayoutManager object, which is responsible for the the layout of the components inside the container

The LayoutManager is consulted whenever there is a need to rearrange the components inside the container (container size changed, component added... )

50unit 15

Example: Layout ManagerExample: Layout Manager

Frame

FlowLayout

add(new Button(“Ok”))

layoutContainer(this)

51unit 15

Layout ManagersLayout Managers

There are various types of Layout Managers, each having its own strategy for arranging components

Layout managers given with java.awt:FlowLayout, BorderLayout, GridLayout, CardLayout, GridBagLayout

You can define your own layout managers by implementing the interface java.awt.LayoutManager

52unit 15

Flow LayoutFlow Layout

A flow layout puts as many components on a row as possible, then moves to the next row

Rows are created as needed to accommodate all of the components

Components are displayed in the order they are added to the container

The horizontal and vertical gaps between the components can be explicitly set

53unit 15

FlowLayoutFlowLayout

setLayout(new FlowLayout());add(new Label(“Name:”));add(new TextField(10));add(new Button(“Ok”));

54unit 15

Border LayoutBorder Layout

A border layout defines five areas into which components can be added

North

South

Center EastWest

55unit 15

BorderLayoutBorderLayout

setLayout(new BorderLayout());add(new Button(“North”), BorderLayout.NORTH);add(new Button(“East”), BorderLayout.EAST);add(new Button(“South”), BorderLayout.SOUTH);add(new Button(“West”), BorderLayout.WEST);add(new Button(“Center”), BorderLayout.CENTER);

56unit 15

GridLayoutGridLayout

setLayout(new GridLayout(2,2));add(new Button(“A”));add(new Button(“B”));add(new Button(“C”));add(new Button(“D”));

Combination of layoutsCombination of layouts

setLayout(new BorderLayout());TextField display = new TextField();add(display, BorderLayout.NORTH);Panel buttonsPanel = new Panel();buttonsPanel.setLayout(new GridLayout(4,4));String[] labels = {“7”,”8”,”9”,”+”,”4”,”5”, ... };for (int i=0; i<labels.length; i++) { buttonsPanel.add(new Button(labels[i]));}add(buttonsPanel,BorderLayout.CENTER);

Panel with

GridLayout

Frame with

BorderLayout

58unit 15

GraphicsGraphics

Every component can serve as a graphical context; in order to draw on a component, you override its paint method to define the drawing

You don’t call the paint method, it is called automatically by the windowing system whenever there is a need to display the component

paint() receives as parameter a Graphics object which has methods for drawing on the component; the widowing system provides the parameter

59unit 15

Example: using GraphicsExample: using Graphics

import java.awt.*;

// A frame that displays some graphics on itclass GraphicsExampleGraphicsExample extends Frame {

public void paint(Graphics painter) { painter.setColor(Color.black); painter.drawLine(20,20,400,300); painter.setColor(Color.blue); painter.drawRect(50,50,150,100); painter.setColor(Color.yellow); painter.fillOval(250,100,80,80); painter.setColor(Color.green); painter.fillRect(100,200,150,100); }}

60unit 15

Graphics: repaintGraphics: repaint()()

In order to display a dynamic drawing, the implementation of paint should depend on the state of the object

Whenever the state changes, we need to call the repaint() method in order to refresh the display of the component

repaint() asks the windowing system to call the paint() method with the suitable graphics object

Actually, the windowing system calls the method update() which clears the display and then calls the method paint()

61unit 15

AWT event handlingAWT event handling

We handle events fired by AWT components by registering listeners to the events they fire

The various events fired by AWT components and the interfaces of the corresponding listeners are defined in the package java.awt.event

62unit 15

AWT events and listenersAWT events and listeners

ActionEvent ActionListener

actionPerformed(ActionEvent)

TextEvent TextListener

textValueChanged(TextEvent)

MouseEvent MouseListener

mouseClicked(MouseEvent)

mouseEntered(MouseEvent)

mouseExited(MouseEvent)

mousePressed(MouseEvent)

mouseReleased(MouseEvent)

MouseMotionListener

mouseDragged(MouseEvent)

mouseMoved(MouseEvent)

... ...

63unit 15

Example: ActionEvent listenerExample: ActionEvent listener

import java.awt.*;import java.awt.event.*;

// A simple ActionListener that prints “clicked”// whenever it is notified of an ActionEventclass SimpleListenerSimpleListener implements ActionListener {

// Called to notify this object that some // action occured public void actionPerformed(ActionEvent event) { System.out.println(“clicked”); }}

64unit 15

Example: listening to button pressExample: listening to button press

// An example of listening to the press of a buttonclass ListeningExampleListeningExample extends Frame {

public ListeningExample() { Button okButton = new Button(“OK”); add(okButton); ActionListener listener = new SimpleListener(); okButton.addActionListener(listener); } public static void main(String[] args) { new ListeningExample().setVisible(true); }}

65unit 15

Example: Drawing PanelExample: Drawing Panel

import java.awt.*;import java.awt.event.*;import java.util.Vector;

// A panel that lets the user draw freehand lines

public class DrawingPanelDrawingPanel extends Panel {

// The points composing the path drawn by the user Vector path;

public DrawingPanel() { addMouseListener(new StartDrawingAdapter(this)); addMouseMotionListener(new DrawingAdapter(this)); }

66unit 15

Example: Drawing PanelExample: Drawing Panel

// Paints this component public void paint(Graphics g) { if (path==null) { return; } for (int i=0; i<path.size()-1; i++) { Point p1 = (Point)path.elementAt(i); Point p2 = (Point)path.elementAt(i+1); g.drawLine(p1.x, p1.y, p2.x, p2.y); } }}

add to Frame object using: add(new DrawingPanel());

67unit 15

Drawing panel: handling eventsDrawing panel: handling events

// Cleans the path at the beginning of the draggingclass StartDrawingAdapterStartDrawingAdapter implements MouseListener {

private DrawingPanel target;

public StartDrawingAdapter(DrawingPanel target) { this.target = target; }

public void mousePressed(MouseEvent e) { target.path = new Vector(); }

public void mouseReleased(MouseEvent e) { } public void mouseExited(MouseEvent e) { } ...}

68unit 15

Drawing panel: handling events Drawing panel: handling events

// Adds the points to the path during the draggingclass DrawingAdapter DrawingAdapter implements MouseMotionListener {

private DrawingPanel target;

public DrawingAdapter(DrawingPanel target) { this.target = target; }

public void mouseDragged(MouseEvent e) { target.path.addElement(e.getPoint()); target.repaint(); }

public void mouseMoved(MouseEvent e) { }

}

69unit 15

AdaptersAdapters

In the previous example we used adapter classes which needed to implement all the methods defined in the interface, sometimes empty

To avoid this effort, the API includes - for every listener interface that defines more than a single method - an adapter class that implements the interface in a trivial way

70unit 15

AdaptersAdapters

package java.awt.event;

// Adapter for MouseEvents ...public abstract class MouseAdapterMouseAdapter implements

MouseListener{

public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { }

public void mouseEntered(MouseEvent e) { }

// ... mouseExited, mouseClicked as well}

71unit 15

Handling events with AdaptersHandling events with Adapters

// Cleans the path at the beginning of the draggingclass StartDrawingAdapterStartDrawingAdapter extends MouseAdapter {

private DrawingPanel target;

public StartDrawingAdapter(DrawingPanel target) {

this.target = target; }

public void mousePressed(MouseEvent e) { target.path = new Vector(); }}

72unit 15

Inner classesInner classes

In the previous examples the main class created adapters to listen to and act upon itself

This adds to the complexity of the code:• the main object has to pass a reference of itself to

the listener/adapter• each listener/adapter has to define a field and a

suitable constructor to record the target object• in each listener/adapter we make frequent use of

the target reference

73unit 15

Inner classesInner classes

To make the code more compact (and less error prone) we may use an inner class - class defined inside the body of another class

An Instance of an inner-class has automatic access to fields defined in the enclosing class, with no need to denote the reference to the enclosing object

74unit 15

Inner classesInner classes

import java.awt.*;import java.awt.event.*;import java.awt.Vector;

// A panel that lets the user draw freehand lines

public class DrawingPanelDrawingPanel extends Panel {

// The points composing the path drawn by the user Vector path;

public DrawingPanel() { addMouseListener(new StartDrawingAdapter()); addMouseMotionListener(new DrawingAdapter()); }

75unit 15

Inner classesInner classes

// Paints this component public void paint(Graphics g) { if (path==null) { return; } for (int i=0; i<path.size()-1; i++) { Point p1 = (Point)path.elementAt(i); Point p2 = (Point)path.elementAt(i+1); g.drawLine(p1.x, p1.y, p2.x, p2.y); } }

76unit 15

Inner classesInner classes

// Cleans the path at the beginning of the dragging class StartDrawingAdapterStartDrawingAdapter extends MouseAdapter {

public void mousePressed(MouseEvent e) { path = new Vector(); } }

// Adds the points to the path during the dragging class DrawingAdapterDrawingAdapter extends MouseMotionAdapter {

public void mouseDragged(MouseEvent e) { path.addElement(e.getPoint()); repaint(); } }}

77unit 15

Anonymous classesAnonymous classes

If an inner class is needed only for a single useand its constructor gets no parameterswe can define it as an anonymous class

Anonymous classes are defined in the place in the code were they are needed, and an instance of the anonymous class is immediately created

Anonymous classes should be used with care - only when the code of the class is very short

78unit 15

Anonymous classesAnonymous classes// .. as beforepublic class DrawingPanelDrawingPanel extends Panel { Vector path; public DrawingPanel() { addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { path = new Vector(); } }); addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { path.addElement(e.getPoint()); repaint(); } }); } public void paint // .. as before}

top related