unit 15: component programming and graphical user interface h component programming h listening to...
Post on 19-Dec-2015
249 views
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}