Title: GSAMS Undistinguished Lecture Series presents . . .
1GSAMSUndistinguished Lecture Seriespresents
. . .
- Graphical User InterfacesApplets, Graphical
Applications,Events Interfaces
2Lecture Contents
- GUIs and the Java AWT
- Graphical User Interfaces / Abstract Windowing
Toolkit - Components as elements of presentation and
interaction - Composition of UIs with containers of components
- Layout of components within containers
- Interaction with GUIs through event-driven
programming
3Graphical User Interface (GUI)
- The name for one variety of user interface
(UI). - An interface in which the user interacts with
objects on the screen (icons, buttons,
scroll-bars, etc.) via mouse clicks or keyboard
actions. (Expressed in the Seeheim model.) - Popularized in 1980s by the Macintosh.
- Now state of the practice, and not final word in
UI - Replaced text-based command line
- and function key interfaces.
- Despite similarities, GUIs are typically
- platform-specific (Windows 95/98/NT,
- MacOS, Xt, NeWS)
4The AWT(Abstract Windowing Toolkit)
- How Java implements a platform-independent GUI
(Graphical User Interface) on different
platforms. - API to the JVMs virtual user interface
- Java 1.0 1.1 GUIs were quite bland because of
the need to be platform-independent. - Related Java 1.2s Swing classes
- create fully-functional GUIs for Java
5Steps to GUI Construction
- In Java, to create a GUI, you (1)
-
- Specify a Container, using . . .
- a Layout Manager to . . .
- place Components and/or Containers of
Components . . . - on the screen as desired.
I.e. UI form and appearance
I.e. UI interaction and behavior
- In Java, to make a GUI act as the interface for a
program, you (2) -
- Design human/computer dialog, using Listeners
and component-generated events
6Lecture Contents
- GUIs and the Java AWT
- Graphical User Interfaces / Abstract Windowing
Toolkit - Components as elements of presentation and
interaction - Classes of components the AWT class hierarchy
- Example declaration presentation Java code
- Composition of UIs with containers of components
- Layout of components within
- containers
7GUI Components
- Most interactions in a Java GUI are with
Components. - Another generic term for Component in other
GUIs (e.g. X Windows) is "widget". - Different types of components for different
types of - interaction (e.g. buttons, etc.)
- User interactions with components create events
(thus, event-driven programming) - As a rule, components cannot have
- other components added to them
- Exception to rule pop up menus may
- have menu items added to them.
-
8The AWT Component Class Hierarchy
Component - generic widget that you can
interact with Button - a widget
that you can press Canvas - a
widget that you can draw on Checkbox -
a widget that is checked or not checked
Choice - an option menu that drops
down Container - a generic class that
contains Components Panel - a
container to be used inside another
container used to split an
existing window Label - a
single line of read-only text List
- a list of Strings Scrollbar
- a horizontal or vertical scrollbar
TextComponent TextArea - multi-line
editable text TextField -
single-line editable text
9Components--Examples
- Canvas
- typically a drawing surface on which shapes,
graphs, pictures, etc can be drawn. - utilize mouse events and mouse motion events to
interact with the user to accomplish the drawing
tasks. - TextField
- a one-line data entry area
- theoretically infinite in length
- can generate Key events to indicate that
- the user has typed a key
- more typically, it generates an Action event
- when the user finishes the data entry and
- hits Return in the TextField.
10Components--Examples
- Button
- simply a clickable label-like component
- appears as a standard button on whatever
graphical environment the user happens to be
running at the time - generates an Action event when clicked
- Label
- a one-line field of text.
- user cannot change this text directly program
changes text with setText( ) method. - usually not used to capture events (but could)
- usually used as a one-way information source
- to provide a message to the user.
11GUI Containers
- Containers are special components that may
contain other components with which the user
interacts. - Examples of Containers
- Panels
- Frames
- Applets
- Note Containment is not the same as extension.
- A Frame may contain buttons,
- but buttons are not subclasses of
- Frame.
12Containers
- Containers are components which can have
- Layouts set on them
- Other components or containers added to them.
- The types of containers include
- 1. Applet
- Generally (but not always) embedded in HTML
- Is automatically created for you as the area of
the web browser or appletviewer in which the
applet loads. - A class that extends Applet
- Is automatically an Applet container,
- Can have a layout set on it and
components/containers added to it.
13Containers
- 2. Frame
- Represents a window on the screen.
- Can have Menu bars on them for pull-down menus
- Can be positioned on the screen via such
methods - public void setBounds(int x, int y, int
width, int height) - public void setLocation(int x, int y)
- 3. Panel
- Is intended as a container/component that can be
added to another container's layout to produce an
embedded or multi-level layout. - Clever use of panels and layouts within
- the panels can produce professional
- and complex interface designs.
14Selecting a Container
Common Top-Level Containers Frame -- familiar
window object with scrollbars, etc. Window --
more basic window object, no scrollbars,
etc. Applet -- embedded byte code inside HTML
document. Instantiation Note Frames and
Windows not self-disposing. (GUI components use
more than just memory Only memory is
garbage-collected by the JVM. Other resources
have to be reclaimed manually by dispose()
) Frame myFrame new Frame() myFrame.setLayout(
new FlowLayout()) myFrame.add(myButtonInstance)
. . . / when done / myFrame.dispose() /
(event handling to come shortly . . .) /
15Containers -- Applets
Special types of containers -- embedded
inside HTML document, between tags
HEIGHT 300 Applets have
no main(String arg) method -- supplied by
browser instead -- Applet lifecycle public
void init () / a main() substitute /
public void start () public void paint
(Graphics g) public void stop () public void
destroy ()
Minimum params others possible
16Containers -- Subclassing
import java.applet.Applet import
java.awt. class myApplet extends Applet
public void init () //define what happens
here public void start ()
//define what happens here public void
paint (Graphics g) //define what happens
here public void stop () //define
what happens here //...etc...
Generally Applets use inheritance while Frames
use composition and/or inheritance
17The Applet Sandbox Model
Applet code runs in 'sandbox within the VM, with
significant restrictions on what it can do.
This is enforced by the SecurityManager class
Work-arounds for applet security restrictions
include digitally signing code, servlettes,
etc. Applications can similarly invoke
SecurityManager objects
18The Applet Sandbox Model
- Untrusted code cannot
- Read files (except from host URL)
- List Directories
- Obtain file information (existence, size, date,
etc.) - Write, Delete, Rename files or directories
- Read or write from FileDescriptor objects
- Listen/Accept on any privileged port
- Call System.exit() or Runtime.ext()
- Create new processes with Runtime.exec()
- Start a print job, access clipboard or event
queue
Remaining weak-spot Denial of Service Attacks
Get full access to System.getProperty(), but it
can use getProperty() to find java.version,
java.class.version, java.vendor, java.vendor.url,
os.name, os.version os.arch, file.separator,
path.separator, line.separator
19Applet Example
/ ReadsFromURL.java -- a trivial applet
demonstrating how to read server-side data
via a URL stream The applet also uses
heavyweights, causing slow redraws
/ import java.awt. import java.applet. import
java.net. import java.io. public class
ReadsFromURL extends Applet protected URL
fileURL protected String result protected
TextArea ta protected int off 15
20/ Default constructor / public
ReadsFromURL() // default constructor for some
fussy VMs / initialize the applet
_at_seereadInURL() -- called to initialize data
/ public void init() setBackground(Color.
lightGray) ta new TextArea()
ta.setFont(new Font("Courier",
Font.BOLD, 12))
21/ Set server to read applet source code
/ try fileURL new URL
(getCodeBase() "/ReadsFromURL.java")
catch(MalformedURLException e)
showStatus("Error!") / Layout the
container / this.setLayout(null) //
necessitates setBounds() add(ta) ta.setBounds(get
Size().width/8, getSize().height/8,
getSize().width3/4, getSize().height3/4) re
adInURL() // init
22/ paint the applet, including borders,
bevels, and screws / public void
paint(Graphics g) // bevels for (int
w0 whg.setColor(Color.white) g.drawLine(w,h,w1,h)
g.drawLine(w1,h,w5,h4)
g.drawLine(w8,h10,w12,h6)
g.drawLine(w12,h6,w13,h6)
g.setColor(Color.darkGray)
g.drawLine(w,h2,w5,h7) g.drawLine(w5,h7,
w6,h7) g.drawLine(w9,h12,w13,h8)
23/ borders / g.setColor(Color.gray)
g.fillRect(0, 0, getSize().width, off)
g.fillRect(0, 0, off, getSize().height)
g.fillRect(getSize().width-off,0,
off,getSize().height) g.fillRect(0,getSize().hei
ght-off, getSize().width, off)
g.fillRect(0,0,2off, 2off) g.fillRect(getSize(
).width-2off,0, 2off, 2off) g.fillRect(0,
getSize().height-2off, 2off, 2off)
g.fillRect(getSize().width-2off,
getSize().height-2off, 2off, 2off) int dX,
dY int x1off int x22off int
x3getSize().width-(12off) int
x4getSize().width-(1off) int y1off
int y22off int y3getSize().height-(12off)
int y4getSize().height-(1off)
24g.setColor(Color.black) g.drawLine(x4,y2,x3,y2)
g.drawLine(x3,y1,x2,y1) g.drawLine(x2,y1,x2,y2)
g.drawLine(x2,y2,x1,y2) g.drawLine(x1,y2,x1,y3)
g.drawLine(x2,y3,x2,y4) g.setColor(Color.white)
g.drawLine(x3,y1,x3,y2) g.drawLine(x4,y2,x4,y3)
g.drawLine(x4,y3,x3,y3) g.drawLine(x3,y3,x3,y4)
g.drawLine(x3,y4,x2,y4) g.drawLine(x2,y3,x1,y3)
//raised outer edge g.setColor(Color.blac
k) g.drawRect(0,0, getSize().width-1,
getSize().height-1) g.setColor(Color.white) g.dr
awLine(0,0, getSize().width-1,0) g.drawLine(0,0,0
, getSize().height-1)
25//screws for (int x2x--0) for (int
y2y--0) dX(x1)?0x3
dY(y1)?0y3 g.setColor(Color.white)
g.drawArc(dXoff/21,dYoff/21,
(int)1.5off,(int)1.5off,90,100)
g.drawLine(dX(int) (1.25off)2,
dY(int) (.75off), dX(int)
(.75off)-1, dY(int) (1.5off)-1)
g.setColor(Color.black) g.drawOval(dXoff/2
,dYoff/2, (int)1.5off,(int)1.5off)
g.drawLine(dX(int) (1.25off)1,
dY(int) (.75off)-1, dX(int)
(.75off)-2, dY(int) (1.5off)-2)
// paint
26public void readInURL() try String
strTemp java.io.InputStream input
fileURL.openStream()
BufferedReader buff new BufferedReader
(new InputStreamReader(input))
while((strTemp buff.readLine()) ! null)
ta.append(strTemp"\n") / Be a good net
neighbor and close the stream! /
buff.close() catch(IOException darn)
showStatus("Exception " darn) //
readInURL // class ReadsFromURL
27GUI Layout
- The problem
- How should components be laid out within a
container? - (Why is this a problem? Because platforms may
differ in screen size / resolution) - AWT Solution
- Layout Managers are AWT classes that encapsulate
policies for laying out components in a
container - Can ensure that the arrangement of objects within
a window will remain proportional regardless
of changes in window dimensions. - Example of general OOD strategy of putting
- rules/policies in a coordinator/referee class.
- A layout manager is always associated
- with a container
28Layout Managers -- Motivation
- One could specify the location of a Component by
specific x and y coordinates. The Component
class contains the method setLocation(int width,
int height) - Button myButton new Button (Click)
- add(myButton) // adds to whatever this
container is - myButton.setLocation(25, 75)
NOTE Origin 0,0 at top left
75 pixels down
Click
Note Buttons x and y coordinate starts from
top left
25 pixels over
29Layout Managers -- Motivation
- Problems with specifying x, y coordinates for
Component - Tedious for even mildly complex GUIs.
- Addition of more components requires
recalculation of every components x, y
coordinate - If container resizes (e.g., user expands
window), calculations have to be redone! - Solution
- Position components based on a percentage
- of available container size. Or create an
- algorithm to place components . . .
- But Java already does this for you . . .
30Layout Managers -- AWT Based
- Java provides several layout managers.
- We will concentrate here on two of them
- BorderLayout
- GridLayout
- To tell a container which layout manager to use,
invoke the method -
- setLayout( )
- and specify a type of layout.
- For example
- To specify a BorderLayout
- setLayout (new BorderLayout())
31LayoutManagers Two General Flavors
- One can conceptually divide layout managers into
two types - Those that attach constraints to their
components. - Those that do not.
- What does this mean? If a manager attaches
constraints to a component, then information - about a components location
- (e.g., compass points) is
- generated with the object.
32LayoutManagers Constraints
- BorderLayout specifies constraints corresponding
to compass - regions of a container
33LayoutManagers Constraints
- BorderLayout then appends constraint information
on all components, e.g. - this.setLayout (new BorderLayout())
- Button e new Button (East)
- Button w new Button (West)
- Button n new Button (North)
- add(e, East) // deprecated
- add(West, w) // works deprecated
- //add(n, BorderLayout.NORTH) // better
34LayoutManagers Constraints
35LayoutManagers Another Example
- import java.awt.
- import java.applet.
- public class test extends Applet
- String Compass "North", "South", "East",
"West", "Center" - public void init()
- / ALWAYS call super init! /
- super.init()
- / set layout /
- setLayout(new BorderLayout())
- for (int i (Compass.length) - 1
- i 0 i- -)
- Button temp new Button (Compassi)
- add (temp, Compassi)
- // for loop
- // test
36LayoutManager Example
37LayoutManager No Constraints
- The second type of LayoutManager does not specify
constraints for the objects it holds. - Examples
- GridLayout()
- FlowLayout()
- Without constraints, you cannot accurately
predict layout behavior across platforms
38LayoutManager No Constraints
- import java.awt.
- import java.applet.
- public class test extends Applet
- public void init()
- super.init()
- String Labels "Short", "Short", "Long
Label", "Really Long Label",
"Really, really long" - setLayout(new FlowLayout())
- for (int i (Labels.length - 1) i 0
i- -) - Button temp new Button
(Labelsi) - add (temp)
- // for
- //init
- //class test
39LayoutManager No Constraints
40LayoutManager No Constraints
41LayoutManager No Constraints
- Note
- Since pixels, fonts and insets vary with each
platform, layout without constraints will vary
greatly. - Lesson
- Use layout managers without constraints only when
you have one or few components
42LayoutManager No Constraints
- Dont think that layout managers without
constraints are not useful! - One of the most useful constraint-free layout
manager is GridLayout. - public GridLayout()
- public GridLayout(int rows, int cols)
- public GridLayout(int rows, int cols,
- int hgap, int vgap)
43GridLayout
GridLayout specifies a grid pattern via
setLayout (new GridLayout (rows, columns)) For
example setLayout (new
GridLayout(2,3)) generates
44GridLayout
- To add components (or containers) to a
GridLayout, particular locations are not
specified (unlike BorderLayout). - Instead, the components (or containers) are
positioned by the sequence in which they are
added, as indicated by numerals below.
1
2
3
4
5
6
45GridLayout
Optionally, two additional parameters may be used
with GridLayout to specify the horizontal and
vertical spacing (in pixels) between grid
elements
setLayout (new GridLayout (rows, columns,
hspace, vspace)) where hspace specifies
horizontal size, and vspace specifies vertical
size, e.g., setLayout (new GridLayout (2,
2, 7, 5))
46GridLayout Example
- import java.awt.
- import java.applet.
- public class test extends Applet
- public void init()
- super.init()
- setLayout(new GridLayout(4,3,5,5))
- int off-2,2,0
- for (int i9 i 1 i--)
- // this is
clever but hard to grok - // thus, is
ill-advised - add (new Button (""(ioffi3)))
- add (new Button ("."))
- add (new Button ("0"))
- add (new Button ("/-"))
- add (new MyPanel(null))
- // init
- //test
47GridLayout Example
48A Layout Example
Imagine that we wish to create an Applet with the
following interface layout . . .
Label One
TextArea1 is here no label displayed
Label Two
Label 3
Button One
Label Four
Button Two
Button Three
(dotted lines do not really appear shown for
reference)
49A Layout Example
- Because this is an Applet, the entire layout is
defined in the init( ) method of the Applet. - Doing this implies three activities
- Sketching the layout on paper.
- Declaring instance variables of the visible
components. - Arranging the components as appropriate using a
combination of nested containers.
50A Layout Example
Step One Sketching the layout on paper
As shown on earlier slide. Step Two
Declaring instance variables
of the visible components TextArea
TextArea1 new TextArea( ) Label Label1
new Label ("Label One") Label Label2
new Label ("Label Two") Label Label3
new Label ("Label 3") Label Label4 new
Label ("Label Four") Button Button1 new
Button ("Button One") Button Button2
new Button ("Button Two") Button Button3
new Button ("Button 3")
51A Layout Example
Step Three Arranging the components
using nested containers
- Consider the overall design in terms of one or
more Layout Managers (for this example,
GridLayout is sufficient). - The Applet itself is a container. Begin there,
and create appropriate subdivisions of screen
space - For this design, the main container is split
into 4 quadrants, each of equal size. - This suggests a grid layout on the Applet, with
- 2 rows and 2 columns, i.e.,
- setLayout (new GridLayout (2,2))
52A Layout Example
- The first quadrant of the GridLayout
- Contains a Text Area component.
- To allocate the instance variable TextArea1 to
the first quadrant, simply add it first -
add (TextArea1)
53- The second quadrant of the GridLayout
- Contains two Labels.
- Since we can have only one container or
component per area, we subdivide the quadrant
into two areas. - To do so, we declare a new Panel, then divide it
as two areas, one for each Label - // create new panel
- Panel Panel1 new Panel()
- // add it to GridLayout
- // at next position
- add (Panel1)
- // subdivide Panel1
- // as 2 rows, 1 column
- Panel1.setLayout (new GridLayout (2,1))
- // add the first two Labels
- Panel1.add (Label1) // 1st area row 1
- Panel1.add (Label2) // 2nd area row 2
54- The third quadrant of the GridLayout
- Contains nothing.
- To "skip a space" in a GridLayout, we add a
"throw-away" panel - add (new Panel())
55- The fourth quadrant of the GridLayout
- Contains several components.
- Because only one component is permitted per
area, we subdivide the space as needed - // create a second Panel
- Panel Panel2 new Panel()
- // add it to the next position
- add (Panel2)
- // divide it into 4 rows, 1 column
- Panel2.setLayout
- (new GridLayout (4,1))
- // add the componets, row by row
- Panel2.add (Label3)
- Panel2.add (Button1)
- Panel2.add (Label4)
56- The fourth quadrant (continued)
- Create room for Button2 and Button3 by
- creating a new Panel3,
- then adding it to Panel2,
- then subdividing Panel3 into 1
- row of 2 columns
- // create the new Panel3
- Panel Panel3 new Panel()
- // add Panel3 to Panel2
- Panel2.add (Panel3)
- // subdivide Panel3
- // into 1 row, 2 columns
- Panel3.setLayout
- (new GridLayout (1,2))
- // add the Buttons to Panel3
- Panel3.add (Button2)
57The final code // declaration section - usually
instance variables TextArea TextArea1 new
TextArea() Label Label1 new Label ("Label
One") Label Label2 new Label ("Label
Two") Label Label3 new Label ("Label
3") Label Label4 new Label ("Label
Four") Button Button1 new Button ("Button
One") Button Button2 new Button ("Button
Two") Button Button3 new Button ("Button
3") Panel Panel1 new Panel() Panel Panel2
new Panel() Panel Panel3 new Panel() // set
up the layout (inside a constructor or init(
)) setLayout (new GridLayout (2,2)) // quadrant
1 - just a textarea. add (TextArea1)
58// quadrant 2 - panel with two labels add
(Panel1) Panel1.setLayout (new GridLayout
(2,1)) Panel1.add (Label1) Panel1.add
(Label2) // quadrant 3 - empty and not used add
(new Panel()) // quadrant 4 - Panel containing
4 rows, last of which// is a Panel containing
two buttons add (Panel2) Panel2.setLayout (new
GridLayout (4,1)) Panel2.add (Label3) Panel2.add
(Button1) Panel2.add (Label4) Panel2.add
(Panel3) Panel3.setLayout (new GridLayout
(1,2)) Panel3.add (Button2) Panel3.add
(Button3)
59Lecture Summary
- GUIs and the Java AWT
- Components as elements of presentation and
interaction - Composition
- Layout of components within containers
- Layout managers encapsulate layout policy
- Containers delegate this responsibility.
- Border layout fits elements close to edges/center
- Grid flow layouts layout spatially if theres
room - For clustered components, use panels
- as sub-containers
- components arranged in panels,
- arranged in panels, in panels...
60GSAMS--Java Course
Interfaces Events
61Java Interfaces
- Java Interfaces
- Multiple inheritance issues
- Adding functionality to a hierarchy
- Adding functionality and a shared interface
to multiple hierarchies - Using interfaces as types
- Event-driven Programming
- Basic model
- Applets
- Events
- Handling Events
- Registering Event Handlers
- Writing Event Handlers
- Debugging Strategies
62Java Interfaces
Means of solving many problems that seem to call
for multiple inheritance.
Example Want to draw Shapes on a Graphics
object.
- Multiple inheritance
- Introduces many annoying complexities.
- Java does not support it.
63Java Interfaces--Partial Solution 1
- We could make a new base class (e.g.,
DrawableShape), giving us both
and
Shape
Square
- Bad idea much redundancy, is anti-OO.
64Java Interfaces--Partial Solution 2
- We could insert a new class into the object
hierarchy . . .
- Bad idea Drawable need not be a propertyof
Shapes, are imposing functionality where it
might not be needed.
65Java Interfaces
Best create interface that allow us to extend
functionality without disturbing class
hierarchies . . .
Makes our diagram more complex, but makes
everything else simpler!
Object
Shape
Circle
Rectangle
Triangle
Square
Drawable
DrawableCircle
DrawableRectangle
DrawableSquare
DrawableTriangle
66Java Interfaces
Example add functionality without disturbing
existing Shape hierarchy, e.g., make our existing
Squares drawable. public interface Drawable
// no constructors! no default methods! just
method headers! public void drawMe (Graphics
g) // of Drawable public class DrawableSquare
extends Square implements Drawable //
"extends" we inherit everything that Square has
- no need to // re-write any constructors,
accessors, modifiers // implements must
have code for drawMe( ) (or at least //
declare it as abstract) in order to satisfy
interface requirements public void drawMe
(Graphics g) g.drawRect
(0,0,iSideSize,iSideSize) // of drawMe //
of DrawableSquare
67Java Interfaces
- Do just what they say provide interfaces.
- Typically concerning shared logical properties.
- Can use to provide shared interface/functionalit
y to multiple independent class hierarchies. - Typically, interface identifiers end in -able or
-ible - Drawable
- Printable
- Edible
- Purchasable
Graphics
TextFile
Printable
PrintableGraphics
PrintableText
68Interface Example
public interface Printable public void
printMe( ) // of interface public class
PrintableText extends TextFile implements
Printable // inherits from TextFile //
must have printMe( ) method to implement
Printable public void printMe( ) //
code to print the text file goes here //
printMe // PrintableText public class
PrintableGraphics extends Graphics implements
Printable // inherits from Graphics //
must have printMe( ) method to implement
Printable public void printMe( ) //
code to print the Graphics object goes here
// printMe // PrintableGraphics
69Interface Example
- Can now use Printable as a type, e.g., . . .
- Can implement a PrinterQueue as an array of
Printables - Printable printerQueue new
Printable10 - The array printerQueue can now handle
anything that implements the Printable
interface. - This is an example of polymorphism at work.
70Interface Details
- Syntax notes re interface methods
- They must be public (cannot be private or
protected). - They must be instance methods (cannot be
static). - They are abstract by default (no need to
explicitly declare them to be abstract). - No variables may be inherited from interfaces.
71Java Interfaces
- Are independent from class hierarchies.
- Can now consider both
- Are you a ?
- Can you do ?
- Use interfaces when
- you want to factor out commonalities among
classes, but - you do not want a relationship between those
classes.
72Example Interface Enumeration
- Enumeration is an interface, not a class.
- Implemented by class Vector and others (e.g.
Hashtable). - May be implemented by any other classes which
are defined to implement it (e.g., linked list,
BST, graph, etc.). - The interface specifies that all classes which
implement Enumeration must implement the two
methods - public boolean hasMoreElements( )
- public Object nextElement( )
73Example Interface Enumeration
- Defines methods needed to enumerate (or iterate
through) a set of values. - Typically, use methods in a loop to see if
theres another element to return and, if so,
to return a reference to it. Makes no promises
about the order in which elements are
encountered. - Values may be iterated through only once there
is no way to reset to the beginning.
74Event Driven Programming
- Traditional programming
- The programs main algorithm governs the flow of
control throughout the program - The general model
- do step A, then do step B, then do C or D,
then - Event-driven programming
- The program waits for the user to do something,
processes that event, then waits for the user
again. - The general model
- loop
- get user event
- process user event
- do something that responds
- to that event
- endloop
75Event Driven Programming Applet Example
- A type of event-driven programming.
- A type of application that uses graphics.
- An applet
- Waits for the user to do something, e.g.,
- move the mouse
- click the mouse
- press a key
- Processes that event
- Does something based on that event
- For example
- the program waits until you press a button,
- the program sees that you pressed a button,
- the program then does something based on the
fact that you pressed that button, e.g., - clear the screen
- restart a game
76Event Driven Programming Applet Example
- Recall the specific stages in an applets
lifecycle. -
- public void init( )
- Called by browser or applet viewer tells
applet that it has been loaded into the
system. Is called once per applet. - public void start( )
- Called by browser or applet viewer, tells
applet to execute. - public void paint(Graphics g)
- Paints the component (draws the component)
tells applet - to paint (draw) the contents of a component.
- public void stop( )
- Called by browser or applet viewer
- tells it to stop execution.
- public void destroy( )
- Called by browser or applet viewer tells
applet that it is - being killed, that it should destroy resources
that it has
77Events
Package java.awt.event features common event
methods actionPerformed(ActionEvent) //
Called if an action occurs in the
//
Component. keyPressed(KeyEvent)
// Called if a character is pressed.
keyReleased(KeyEvent) // Called if
a character is released.
mousePressed(MouseEvent) // Called if the
mouse is down. mouseDragged(MouseEvent) //
Called if the mouse is dragged
mouseEntered(MouseEvent) // Called when the
mouse enters
// component.
mouseExited(MouseEvent) // Called when the
mouse exits the
// component.
mouseMoved(MouseEvent) // Called if the
mouse
// moves (button is up)
mouseReleased(MouseEvent) // Called if the
mouse
// button is released.
78Handling Events
- Any component, such as
- a Button
- a Canvas
- a Menu, etc.
- can have events happen to it.
- For example, a user can
- select a menu item from a Menu
- drag the mouse over a Canvas
- type text into a Text Field
- click on a Checkbox
- etc., etc.
- To avoid slow-downs in program execution, Java
does not automatically "handle" any of these
events . . . unless the programmer explicitly
tells Java to do so.
79Handling Events -- How
In order to capture an event, you need to have an
appropriate event listener". An event listener
is an interface which specifies some
event-handling methods for the particular type of
event to be handled. For example an
ActionListener specifies the method
public void actionPerformed(ActionEvent
) For a complete listing of the
listeners and the methods they require, refer to
p.151 of Java in a Nutshell, or the
java.awt.event. package.
80Registering Event Handlers
- To have Java use the event listener, you must
tell Java to do so by registering the event - To register a specific event, use addListener
methods built into each component. - For example, a Button or MenuItem has the
method - addActionListener(ActionListener
a) - to add an action listener to itself.
- Adding an action listener specifies that,
whenever that Button or MenuItem gets an
action event, it will call the method
actionPerformed( ) on all the actionListeners
that have - been added to it
- Because interfaces are contracts, Java
guarantees - that any class that implements the
ActionListener - interface must provide code for actionPerformed(
)
81Writing Event Handlers
- To write an event handler
- Have a class that implements one or more of
the Listener interfaces. - To "catch" the event
- Write code for the appropriate event handler
specifying the response to the event. - Then, register your event handler class with
the addListener method of the component whose
event you want to catch.
82Writing Event Handlers Example
import java.applet.Applet import
java.awt. import java.awt.event. public
class simpleApplet extends Applet implements
ActionListener Button other, printHello
Canvas myCanvas public void init( )
// set up "other" button have its
action event go here other new Button(
"other" ) other.addActionListener
(this) // set up "printHello" button
action event go here printHello new
Button( "Print Hello World" )
printHello.addActionListener (this)
83 // set up Canvas to draw on
myCanvas new Canvas( ) // place
components on screen setLayout( new
BorderLayout( ) ) add( printHello,
"North" ) add( other, "South" )
add( myCanvas, "Center" ) // init
public void actionPerformed ( ActionEvent evt )
// print a simple message to see what
button was pressed // getSource( )
returns a reference to the object that //
caused the event to happen
if ( evt.getSource( )
other ) System.out.println( other
pressed. ) else
System.out.println( Print 'Hello World'
pressed. ) repaint( ) //
actionPerformed
84 public void paint( Graphics g )
System.out.println( "paint( ) called" )
myCanvas.getGraphics( ).drawString( "painting!",
0, 115 ) myCanvas.getGraphics(
).setColor( Color.magenta )
myCanvas.getGraphics( ).fillOval( 220, 220, 50,
50 ) myCanvas.getGraphics( ).setColor(
Color.black ) myCanvas.getGraphics(
).drawOval( 220, 220, 50, 50 ) //
paint // simpleApplet
85Event Handling General Options
Four general options for event handling 1.
Event Listeners -- use
interfaces. Good for low-level control. 2.
Event Adapters -- use objects. More
selective. 3. Semantic Events
-- for simple event handling. 4. Old JDK
1.02 events --not recommended useful
in rare circumstances
86Option 1 Event Listeners
As noted, one can addXYZListener to a
component, e.g. class TestApplet extends
Applet implements MouseListener
Button myButton public void
init() myButton new Button(Click)
myButton.addMouseListener(this)
. . . // TestApplet When using
listener interfaces, one must code all event
methods--even those we are not interested in.
Wasted code arises public void
mouseEntered(MouseEvent e) public void
mouseExited(MouseEvent e) public void
mouseClicked(MouseEvent e) public void
mouseReleased(MouseEvent e) public void
mousePressed
(MouseEvent e) / handle mouse event /
no-op methods
Single method we do something in
87Option 2 Event Adapters
In addition to interfaces, the java.awt.event.
package provides adapter classes that can be
subclassed. No need to code every method just
override the method you need
Public class EventHandler extends MouseAdapter
public void mouseEntered(MouseEvent
e) public void mouseExited(MouseEvent
e) public void mouseClicked(MouseEvent
e) public void mouseReleased(MouseEvent
e) public void mousePressed(MouseEvent
e) / handle mouse event /
Less wasted code but you use up your single
inheritance!
88Event Adapters Registration
public class TestApplet extends Applet private
Button myButton private EventHandler
handle public void init() handle new
EventHandler(this) myButton new
Button(Click) myButton.addMouseListener(this)
. . . . . . . . . public void
takeActions() . . . . public class
EventHandler extends MouseAdapter TestApplet
myApplet public EventHandler(TestApplet
myApplet) this.myApplet myApplet
public void mousePressed(MouseEvent
e) myApplet .takeActions()
Passing this allows for call-backs
Event handled by accessing applet
89Option 3 Semantic Events
The foregoing options (interfaces and objects)
involved low-level events. Event processing may
also occur through the use of semantic
events. Unlike listeners/adapters, these are
high-level, component-based events. They
essentially funnel a variety of low-level
events into a single method. NOTE You lose
ability to catch small, granular events (e.g.,
mouseEntered/Exited are not possible). Since ALL
events delivered to a few methods, event
handling relies on complex, linear if/else
structures.
90Semantic Events
Semantic Event
Components and Firing Event
ActionEvent
Button (activated)
List (double-clicked)
MenuItem (selected)
TextField (typed)
AdjustmentEvent
Scrollbar (moved)
ItemEvent
Checkbox (toggled) CheckboxMenuItem
(selected) Choice (selected) List (selected)
TextEvent
TextComponent (text changes)
91(non) Option 4 JDK 1.02 Events
- An earlier version of Java used boolean return
values to indicate consumption of events - Not recommended still used for some web
development - Do not mix JDK 1.1 and JDK 1.02 event
handlers--the component ceases to function. - Rare use JDK 1.02 guarantees which event will
arrive first to a component.
92Event Handling Options How to Decide
Costs Benefits
Event Listeners (interfaces) Event
Adapters (inheritance) Semantic Events
Must code all methods wasteful no-ops result
Keep all events in single class
Uses up single inheritance opportunity
Good abstraction override those methods you need
Simplifies event handling
Loss of granular control linear code
93Debugging re Event Handlers
- Debugging an event-driven program (whether
applet or graphical application) is more
tricky than debugging a non-event-driven
program. - With an event-driven Java program, you don't
explicitly code any kind of event-handling loop
that "polls" for occurring events, then calls
the appropriate handler(s) for those events. - Instead, the Java internals handle this polling
action for you. Debugging becomes trickier
because now you have to make sure that your
event handling code works correctly. - You also have to make sure you're handling the
- correct events in the first place! For
example, - your code for mouseEntered( ) may work
perfectly, - but if you're expecting it to get called when
the user clicks a mouse button, it won't be!
94Debugging re Event Handlers
- So, in debugging event-driven programs written
- with Java, the steps are
- Be sure you're handling the appropriate events
- Map out on paper what events get thrown from
what components, and what class(es) handle
them. - Handle the events appropriately This is the
kind of debugging you're already familiar with
Once you're sure the appropriate events - are getting handled, the rest is being sure
- the event-handling code (and the code that
- the event handlers call) work.
95Example Create a Paint Applet
Goal create applet that Allows user to
draw with mouse Mouse drag draws
Mouse up stops drawing Pen color
selectable Button to clear canvas Will
show three versions, each using different event
handling techniques
96Design 1 Interfaces Only
1. List Basic Components/Containers java
.applet.Applet --java.awt.Canvas
--java.awt.Panel
---java.awt.Button
---java.awt.Choice ---java.awt.Label
2. List Basic Behaviors mouse drag
draws button clears canvas choice changes pen
color canvas knows whether to draw (mouse
drag) or not (mouse is up)
97Design 1 Interfaces Only
3. Outline classes, assigning from two lists
a. Drawing Canvas subclass -- paint
method draws -- has reference to
controls -- boolean flags for
clear/draw b. Control panel Panel
subclass -- has Button, Label, Choice
-- sets flags in canvas to clear/ change
color, etc. -- has reference to canvas
c. Top container Applet subclass --
BorderLayout -- Introduces classes to
each other -- Sets some
initial values
98General Layout
Applet (BorderLayout) -- add Canvas to
CENTER -- add ControlPanel to SOUTH --
set initial values (size of canvas, pen color)
ControlPanel (GridLayout)
Widgets (Button, Label, Choice)
99Design 1 Class Structure
MANDATORY Plan your cross-class
communications
In this version, events are handled by a Control
Panel In such a case, how to send
events to Canvas? Cross-class
communications! The control panel has a
reference to the DrawCanvas, and the canvas has a
reference to the ControlPanel instance (ver 1).
Alernatively (ver 2), both have reference to
Applet, which provides reference to components
Calls (ver 2)
calls (ver 2)
Q
A
calls (ver 1)
100Version 1 Interfaces
import java.applet.Applet import
java.awt. public class DrawApplet extends
Applet private ControlPanel controls
private DrawCanvas canvas public void init()
this.setLayout(new BorderLayout())
canvas new DrawCanvas( (int) (getSize().width
.75),
(int) (getSize().height .75) )
controls new ControlPanel() /
introduce the components to each other /
canvas.setControls(controls)
controls.setCanvas(canvas)
canvas.setColor(Color.red) add(canvas,
BorderLayout.CENTER) add(controls,
BorderLayout.SOUTH) // init // class
DrawApplet
101import java.awt. import java.awt.event. public
class ControlPanel extends Panel implements
MouseListener,
ItemListener private DrawCanvas
canvas private Button clearButton private
Label label private Choice colorChoice
public ControlPanel() this.setLayout(new
GridLayout(1, 3)) clearButton new
Button("Clear") label new Label("Select
Pen Color") colorChoice new Choice()
colorChoice.add("Red") colorChoice.add("Blue"
) colorChoice.add("Green")
colorChoice.addItemListener(this)
clearButton.addMouseListener(this)
add(clearButton) add(label) add(colorChoice)
// constructor public void
setCanvas(DrawCanvas canvas) this.canvas
canvas // setCanvas
102/ class ControlPanel (contd) . . . / public
void mousePressed(MouseEvent e) if
(e.getSource() clearButton)
canvas.setClear(true)
canvas.repaint() // if //
mousePressed public void itemStateChanged
(ItemEvent e) int index
colorChoice.getSelectedIndex()
switch(index) case 0//red
canvas.setColor(Color.red) break case
1 // blue canvas.setColor(Color.blue)
break case 2
canvas.setColor(Color.green) break
// switch (whats wrong with it?)
// itemStateChanged
103/ wasted code / public void mouseReleased
(MouseEvent e) // mouseReleased
public void mouseClicked (MouseEvent e)
// mouseClicked public void
mouseExited (MouseEvent e) //
mouseExited public void mouseEntered
(MouseEvent e) //
mouseEntered // class ControlPanel
104import java.awt. import java.awt.event. public
class DrawCanvas extends Canvas
implements MouseMotionListener,
MouseListener private int mouseX, mouseY,
oldX, oldY private boolean bClear, bDrawing
private Color color private ControlPanel
controls public DrawCanvas(int width, int
height) this.setSize(width,height)
this.addMouseListener(this)
this.addMouseMotionListener(this) //
constructor public void setControls(ControlPan
el controls) this.controls controls
// setControls public void
updateCoordinates(MouseEvent e)
updateCoordinates(e.getX(), e.getY()) //
updateCoordinates
105 / class DrawCanvas (contd) . . . /
public void updateCoordinates(int x, int y)
oldXmouseX oldY mouseY mouseXx
mouseYy repaint() //
updateCoordinates public void
setDrawing(boolean bDrawing)
this.bDrawing bDrawing // setDrawing
public void setClear(boolean bClear)
this.bClear bClear // setClear public
boolean getDrawing() return bDrawing
// getDrawing public boolean getClear()
return bClear // getClear
106/ class DrawCanvas (contd) . . . / public
Color getColor() return color //
getColor public void setColor(Color color)
this.color color // setColor
public void update(Graphics g)
paint(g) // update public void paint
(Graphics g) if (getClear())
g.setColor(Color.white)
g.fillRect(0,0,getSize().width,
getSize().height) setClear(false)
// if if (getDrawing())
g.setColor(getColor()) g.drawLine(oldX,
oldY, mouseX, mouseY) // if //
paint
107public void mouseDragged (MouseEvent e)
updateCoordinates(e) repaint()
// mouseDragged / below is wasted code /
public void mouseClicked
(MouseEvent e) // mouseClicked public
void mouseExited (MouseEvent
e) // mouseExited // class DrawCanvas
/ class DrawCanvas (contd) . . . / public
void mouseMoved(MouseEvent e)
updateCoordinates(e) // mouseMoved public
void mouseEntered(MouseEvent e)
updateCoordinates(e) // mouseEntered public
void mousePressed(MouseEvent e)
setDrawing(true) updateCoordinates(e)
repaint() // mousePressed public void
mouseReleased (MouseEvent e)
setDrawing(false) updateCoordinates(e
) repaint() // mouseReleased