CS2 - PowerPoint PPT Presentation

1 / 123
About This Presentation
Title:

CS2

Description:

Behind the scenes, the Java runtime environment is monitoring many things ... Frist, we make a JFrame subclass. We declare some instance ... – PowerPoint PPT presentation

Number of Views:39
Avg rating:3.0/5.0
Slides: 124
Provided by: davidd1
Category:
Tags: cs2 | frist

less

Transcript and Presenter's Notes

Title: CS2


1
CS2
  • Module 35
  • Category Elements of Java
  • Topic GUI Events
  • Objectives
  • Events
  • Interclass Communication

2
CS 2
  • Introduction to
  • Object Oriented Programming
  • Module 35
  • Elements of Java
  • GUI Events

3
Nota Bene
  • This lecture presentation contains a number of
    "hidden" slides. Feel free to read, study and
    learn from them on your own!

4
Today's Plan for Fun
  • Events
  • What is an event?
  • Simple (?) Example
  • Swing Components
  • JFrames
  • JComponents
  • An example
  • Swing Component Design (MVC/UI-Delegate)

5
Events
  • Behind the scenes, the Java runtime environment
    is monitoring many things
  • When any of a number of things happen an event is
    said to occur. Sometimes the terminology is an
    event gets fired"
  • Examples of the types of things that can "fire"
    events
  • Pressing a key on the keyboard
  • Clicking on a component (like a button)
  • Entering a component with the mouse pointer
  • Have a timer "time-out"

6
Events
  • Moving the mouse around any reasonably
    complicated GUI can literally cause hundreds if
    not thousands of events to occur
  • Events will be ignored except for the ones that
    you tell Java that you are interested in doing
    something about
  • Java maintains a data structure of all the events
    that you have decided to handle and looks up
    events and does what you tell it to do.

7
Remember this???
  • import java.awt.
  • public class HelloGUI
  • public static void main (String arg)
  • System.out.println("About to make GUI")
  • Frame f new Frame ("Hello GUIs")
  • f.setSize( 200, 200 )
  • f.show()
  • System.out.println("Finished making
    GUI")
  • // main
  • // class HelloGUI

8
What didn't work???
9
Making it work
  • Determine which event occurs when the "Close the
    Window" button is pressed
  • The API is your friend
  • The lecture notes are your friend
  • Hint In this case it's an event called "Window
    Closing"
  • You decide what class is going to handle this
    event
  • It might be the actual class which has the window
  • It can be any other class
  • Write the method (and class?) that will handle
    the event. When this event occurs, Java is going
    to go to the class that you identify as the event
    handler or Listener. It will look for a method
    called
  • public void windowClosing(WindowEvent e)
  • Java will report an error to you if this class
    doesn't have this method. How might the designers
    of Java be guaranteed that you will implement
    this method?

10
An Interface!!!
  • // Note found in java.awt.event
  • public interface WindowListener
  • extends EventListener
  • void windowActivated(WindowEvent e)
  • void windowClosed(WindowEvent e)
  • void windowClosing(WindowEvent e)
  • void windowDeactivated(WindowEvent e)
  • void windowDeiconified(WindowEvent e)
  • void windowIconified(WindowEvent e)
  • void windowOpened(WindowEvent e)

11
So we could write a class like this
  • import java.awt.
  • import java.awt.event.
  • public class Handler implements WindowListener
  • public void windowActivated(WindowEvent e)
  • public void windowClosed(WindowEvent e)
  • public void windowClosing(WindowEvent e)
  • Window w e.getWindow()
  • w.setVisible(false)
  • w.dispose()
  • System.exit(0)
  • public void windowDeactivated(WindowEvent e)
  • public void windowDeiconified(WindowEvent e)
  • public void windowIconified(WindowEvent e)
  • public void windowOpened(WindowEvent e)

12
Making it work II
  • Register the listener with Java. That is, tell
    Java in which class the method will be located to
    run when the Window Closing Event occurs.

13
Registration
  • import java.awt.
  • public class HelloGUI
  • public static void main (String arg)
  • Handler h new Handler()
  • System.out.println ("About to make GUI")
  • Frame f new Frame ("Hello GUIs")
  • f.setSize( 200, 200 )
  • f.addWindowListener(h)
  • f.show()
  • System.out.println("Finished making GUI")
  • // main
  • // class HelloGUI

14
Demonstration
15
Diagramatically
Class Pool
class HelloGUI main Frame f Handler
h
class Frame
class Handler
Interface WindowListener
Frame Instance
Handler Instance
16
Key Ideas
  • Determine which event occurs
  • Decide what class is going to handle this event
  • Write the method (and class?) that will handle
    the event.
  • Register the listener with Java.

17
Questions?
  • Very important that you understand this simple
    example to understand the concepts that follow.

18
Potential Points of Confusion
  • What exactly is the listener? Is it the component
    getting clicked on?
  • No, the listener is the object that contains the
    method that Java will call when the event
    happens.
  • You must tell the component getting clicked which
    object that is by registering addWindowListener..
    .
  • As we will see it could be the same!!!
  • What type of listener do I use?
  • There are only so many
  • See the API
  • Lecture/Instructor/Recitation/TA/etc.
  • Experience!
  • What about all those other window things (e.g.
    windowActivated)
  • We actually did implement them (with empty
    bodies)
  • We said Don't do anything!

19
Questions?
20
Today's Plan for Fun
  • Events
  • What is an event?
  • Simple (?) Example
  • Swing Components
  • JFrames
  • JComponents
  • An example
  • Swing Component Design (MVC/UI-Delegate)

21
Recall
Earlier, we cautioned about the existence of two
toolkits in Java for creating GUIs AWT Swing

Today, we examine a few Swing components. The
goal is to learn how Swing components in general
are designed, so that you can make better use of
the API.
22
Swing?
In 1997, Sun announced a new graphical toolkit
for Java called the Java Foundation Classes, or
JFC. This is usually called Swing. The
JFC/Swing classes provide well designed, powerful
widgets for GUI developers. Lets take a look .
. .
23
JFC/Swing
  • Now it gets interesting . . .

24
Historical Problems with AWT
  • All AWT components required runtime peer
    resources
  • slow on some platforms (notably Windows)
  • portability problems (slightly different look,
    some behaviors different)
  • least common denominator phenomenon If one OS
    (e.g., Windows) did not support a widget, the
    entire AWT had to suffer without it.
  • Limited AWT widget library
  • addressed somewhat by JDK 1.1b3, which allowed
    subclassing of components, or lightweights (not
    covered in this course)

25
Stop-gap remedies for JDK 1.1b3
  • Developers avoided a few AWT limitations through
  • Pervasive use of lightweights (again, not covered
    in cs1312).
  • e.g., tooltip simulation through
    threads/windows/components
  • extensive coding around rigid look
  • use of layered gifs

Bottom line Making stuff look cool or satisfying
a clients request could be a nightmare!
26
Introducing Swing/JFC
  • Sun addressed these problems by producing Java
    Foundation Classes (JFC) a.k.a. Swing
  • Key elements
  • No reliance on native peers the JVM does the
    work, and is faster
  • Swing completely controls look and feel of all
    components
  • PLAF, or pluggable look and feel
  • Superior design MVC-esque (Model View Control)

Fast, flexible, extensible!
27
Swing Packages
  • All the new Swing components and classes need a
    home. Where?
  • A subject of great debate!
  • For JDK 1.1, Sun used com.sun.java.swing
    developers revolted.
  • Problem developers complained this com
    designation was not appropriate for core
    class--something part of language.
  • Solution

Why javax? logical grouping minimizes
transition costs most developers happy with
it helps maintain existing JDK 1.1 code (cf.
MFC lib breaks)
javax.swing.
Denotes extension package that has migrated to
core status
28
Overview of JFC/Swing Packages
  • javax.swing
  • javax.swing.table
  • javax.swing.tree
  • javax.swing.border
  • javax.swing.colorchooser
  • javax.swing.filechooser
  • javax.swing.event
  • javax.swing.undo
  • javax.swing.plaf
  • javax.swing.plaf.basic
  • javax.swing.plaf.metal
  • javax.swing.plaf.multi
  • javax.swing.text
  • javax.swing.text.html
  • javax.swing.text.html.parser
  • javax.swing.text.rtf

29
Overview of the Overview
Components, including aggregate or
complex components
Packages to control the look and feel of Swing
Text-based widgets (including html/rtf display)
New event packages
30
Getting into the Swing
  • Download from www.javasoft.com
  • Swing works with JDK 1.1 and JDK 1.2
  • JDK 1.1 requires swingall.jar file in the
    CLASSPATH
  • For JDK 1.2, its already included (no CLASSPATH
    settings needed)
  • JDK 1.2 will also run all JDK 1.1 code ( 20
    faster!)
  • Thus, even older JDKs can make use of Swing, with
    a CLASSPATH setting.

import com.sun.java.swing.
import javax.swing.
AWT
JDK 1.1
classpath
swingall.jar
31
Short Examples
1.
32
Short Example Old AWT
import java.awt. public class HelloWorld
extends Frame public Button bOld
//public Panel p public HelloWorld()
bOld new Button ("Good Bye") //p new
Panel() //p.add(bOld) //this.add(p)
this.add(bOld) / note the addition
directly to the Frame / this.pack()
public static void main(String arg) /
note lack of listener this is a demo / new
HelloWorld().show() // class HelloWorld
We comment most of this out for now AWT lets us
add directly to the Frame.
33
Hello Swing, Good Bye AWT
  • import java.awt.
  • import java.awt.event.
  • import javax.swing.
  • public class HelloWorld extends JFrame
  • Button bOld public JButton bNew
  • public JPanel p
  • public HelloWorld()
  • bNew new JButton("Hello")
  • bOld new Button ("Good Bye")
  • p new JPanel()
  • p.add(bNew) p.add(bOld)
  • this.getContentPane().add(p)
  • this.pack()
  • public static void main(String arg)
  • new HelloWorld().show()
  • // class HelloWorld

Note Swing components
Note addition of components to JPanels
content pane
SEE CAUTIONARY NOTE RE Mixing light and
heavyweight components!
34
Whats the Big Deal?
  • HelloWorld looks similar to AWT. Why switch to
    JFrame, JButton, JPanel, etc?
  • Benefits
  • speed
  • lightweight flexibility (transparency,
    non-rectangular shape)
  • pluggable look and feel
  • automatic double buffering with many J-
    components.
  • additional functionality (e.g., tooltips, etc.)

Im lightweight, pluggable, extensible and fast.
The VM draws me.
I need Windows to be visible and toggle. Im
slow.
35
Widget Example JButtons
  • The java.swing.JButton class implements a state
    version of a java.swing.AbstractButton. Many
    methods come from the abstract class
  • A variety of constructors (Strings, Icons, etc.)
  • setRolloverEnabled(boolean)
  • setIcon(Icon)
  • setRolloverIcon(Icon)
  • setActionCommand(String) -- an extra String
    tacked onto the event that gets fired!
  • setContentAreaFilled(boolean) -- transparency for
    icons!
  • setModel(ButtonModel) -- sets the type of
    Button (you can define your own Button
    behaviors!)
  • setMnemonic(char/int) -- set mnemonics for button

Lesson Check the API for useful behaviors.
36
Cool Buttons
  • import javax.swing.
  • public class HelloWorld2 extends JFrame
  • public JButton bNew
  • public JPanel p
  • public HelloWorld2()
  • bNew new JButton("New Document", new
  • ImageIcon("Document.gif"))
  • bNew.setRolloverEnabled(true)
  • bNew.setRolloverIcon
  • (new ImageIcon ("New.gif"))
  • p new JPanel()
  • p.add(bNew)
  • getContentPane().add(p)
  • this.pack()
  • public static void main(String arg )
  • new HelloWorld2().show()
  • // class HelloWorld2

Sets icon and rollover Icon. Note Icon
constructor took String argument, and
automatically loaded image
37
Demonstration
38
Why getContentPane() ?
  • The HelloWorld example required us to call
    getContentPane() before add()ing an object to
    the JFrame

myFrameInstance.getContentPane().add(myComponent)
Required of JFrame, JDialog and
JInternalFrame instances
Usually this
E.g., myJButton
  • This differs from traditional AWT container
    additions, where we simply call add, passing in
    the component.
  • Lets cut a JFrame open to find out why . . .

39
A JFrame Autopsy
The Pop Tart / Sandwich Duality
40
JFrame Class View
Component
AWT
GlassPane
Frame
Container
contains
manages
ContentPane
JComponent
JFC
contains
JMenuBar
manages
JRootPane
JFrame
contains
contains
The JRootPane is a container with a JLayeredPane
(holding the Menu and ContentPane) and a
Component GlassPane. It serves as base for
numerous classes.
contains
JLayeredPane
41
JRootPane The Content Pane
The JRootPane contains only two components
the JLayeredPane and the Component
GlassPane Its layout manager ignores all
attempts to add new components. Instead, one
must add to the JRootPanes ContentPane, found
inside the JLayeredPane. A call to
getContentPane() returns an instance of the
ContentPane.
42
JRootPane The Glass Pane
public Component getGlassPane() public void
setGlassPane(Component)
We can use the top glassPane as a drawing area.
Since it spans the entire JFrame, we can draw on
top of menu bars, and every component.
The JPanel has a remarkable layering feature,
allowing us to stack and shuffle components.
public JPanel getContentPane()
43
JFrame Disposal
  • JFrame allows you to configure how it responds to
    closure.
  • Default hides JFrame on closure attempt.
  • To modify invoke setDefaultCloseOperation().
  • E.g.,
  • MyJFrameInstance.setDefaultCloseOperation
  • (WindowConstants.DO_NOTHING_ON_CLOSE)
  • / behaves just like java.awt.Frame /
  • other constants in javax.swing.WindowConstants
  • HIDE_ON_CLOSE - invokes any registered
    WindowListener object, then hides. This is
    default behavior.
  • DISPOSE_ON_CLOSE - invokes any registered
    WindowListener object, and then disposes.

44
Questions?
45
Questions?
46
JComponent The Generic Widget
  • The JComponent provides the basis for all Swing
    components.
  • JComponent extends java.awt.Container, making all
    Swing components large, powerful widgets.
    (Also, all Swing components are also
    containers--even if you wouldnt normally place
    things in them. E.g., JButton)
  • In turn, JComponent is subclassed by numerous
    widgets. Thus, composition is favored over
    inheritance for widget manipulation.

47
JComponent
Since JComponent is the basis for most Swing
components, all Swing widgets have the following
general features Borders -- JComponent derived
classes can have borders Accessibility
-- JComponents use Swings accessibility
features to provide additional information about
the widget. Tooltips --
JComponents can have time sensitive
tooltips. Double Buffering -- By
default, Swing components have double buffering
built in Serialization -- Ability
to save state to a file.
48
Demo A GlassPane Example
import java.awt. import java.awt.event. import
javax.swing. public class GlassDemo extends
JFrame implements ActionListener private
boolean bGlassVisible private GlassPanel
glass private JButton button
This demo will not be covered in class it is
provided as an example of how to work with
JFrames.
Heres a simple example that shows how to use
aspects of JFrames. Frist, we make a JFrame
subclass. We declare some instance variables a
GlassPanel (described later), a boolean flag
for the glass panels visibility, and a JButton
to toggle
49
Glass Panel Example
import java.awt. import java.awt.event. import
javax.swing. public class GlassDemo extends
JFrame implements ActionListener private
boolean bGlassVisible private GlassPanel
glass private JButton button public
void actionPerformed (ActionEvent
e) bGlassVisible !bGlassVisible glass.setVis
ible(bGlassVisible)
The actionPerformed method merely toggles the
visibility of the glass pane
50
Glass Panel Example
import java.awt. import java.awt.event. import
javax.swing. public class GlassDemo extends
JFrame implements ActionListener private
boolean bGlassVisible private GlassPanel
glass private JButton button public
void actionPerformed (ActionEvent
e) bGlassVisible !bGlassVisible glass.setVis
ible(bGlassVisible) public void
centerInScreen() Toolkit tk
Toolkit.getDefaultToolkit() Dimension d
tk.getScreenSize() this.setLocation((d.width-get
Size().width)/2, (d.height-getSize().height)
/2)
... A little magic. (It merely centers the
frame in the screen.)
51
Glass Panel Example
import java.awt. import java.awt.event. import
javax.swing. public class GlassDemo extends
JFrame implements ActionListener private
boolean bGlassVisible private GlassPanel
glass private JButton button public
void actionPerformed (ActionEvent
e) bGlassVisible !bGlassVisible glass.setVis
ible(bGlassVisible) public void
centerInScreen() Toolkit tk
Toolkit.getDefaultToolkit() Dimension d
tk.getScreenSize() this.setLocation((d.width-get
Size().width)/2, (d.height-getSize().height)
/2) public static void main(String
args) new GlassDemo().show()
A simple test main
52
public GlassDemo () this.setSize(400,400) thi
s.getContentPane().setBackground(Color.white) th
is.getContentPane().setLayout(new
BorderLayout()) this.addWindowListener (new
WindowAdapter() public void windowClosing(Windo
wEvent e) System.exit(0) )
Our constructor has poor abstraction, but is
sufficient for a demonstration. We start by
setting a size, background, layout, and a simple
WindowListener
53
public GlassDemo () this.setSize(400,400) thi
s.getContentPane().setBackground(Color.white) th
is.getContentPane().setLayout(new
BorderLayout()) this.addWindowListener (new
WindowAdapter() public void windowClosing(Windo
wEvent e) System.exit(0) ) JPanel p
new JPanel() p.setLayout(new BoxLayout(p,
BoxLayout.X_AXIS)) button new JButton
("Toggle") button.addActionListener(this) p.ad
d(Box.createHorizontalGlue()) p.add(button) p.
add(Box.createHorizontalGlue())
We add a JButton to a containing JPanel. We
make sure it will center in the JPanel, using
glue objects. The same effect can be obtained
with more complicated layerings of panels and
layout managers.
54
public GlassDemo () this.setSize(400,400) thi
s.getContentPane().setBackground(Color.white) th
is.getContentPane().setLayout(new
BorderLayout()) this.addWindowListener (new
WindowAdapter() public void windowClosing(Windo
wEvent e) System.exit(0) ) JPanel p
new JPanel() p.setLayout(new BoxLayout(p,
BoxLayout.X_AXIS)) button new JButton
("Toggle") button.addActionListener(this) p.ad
d(Box.createHorizontalGlue()) p.add(button) p.
add(Box.createHorizontalGlue()) this.getContentP
ane().add(p, BorderLayout.CENTER) this.getConten
tPane() .add(new JLabel("Press Button to
Toggle Glass Pane"), BorderLayout.SOUTH)
We add the panel to our JFrames content
pane, along with a simple label. . .
55
public GlassDemo () this.setSize(400,400) thi
s.getContentPane().setBackground(Color.white) th
is.getContentPane().setLayout(new
BorderLayout()) this.addWindowListener (new
WindowAdapter() public void windowClosing(Windo
wEvent e) System.exit(0) ) JPanel p
new JPanel() p.setLayout(new BoxLayout(p,
BoxLayout.X_AXIS)) button new JButton
("Toggle") button.addActionListener(this) p.ad
d(Box.createHorizontalGlue()) p.add(button) p.
add(Box.createHorizontalGlue()) this.getContentP
ane().add(p, BorderLayout.CENTER) this.getConten
tPane() .add(new JLabel("Press Button to
Toggle Glass Pane"), BorderLayout.SOUTH) cen
terInScreen() glass new GlassPanel() this.se
tGlassPane(glass) bGlassVisible false
// end of class GlassDemo
We then make and set a new glass panel for the
JFrame.
56
import java.awt. import javax.swing. public
class GlassPanel extends JComponent final
Color trans public GlassPanel ()
this.setOpaque(false) // create nearly black
color with transparency trans new
Color(150,25,25,125) public Dimension
getPreferredSize() return getParent().getPreferr
edSize() public void
paintComponent(Graphics g) g.setColor(trans) g
.fillRect(0,0,getSize().width, getSize().height)
// GlassPanel
57
import java.awt. import javax.swing. public
class GlassPanel extends JComponent final
Color trans public GlassPanel ()
this.setOpaque(false) // create nearly black
color with transparency trans new
Color(150,25,25,125)
Our GlassPanel object is merely a JComponent
subclass. It first sets itself to be
transparent, and then creates a color with a
high transparency value, 125. (A later lecture
will touch on the Java color model. For now,
the API shows us the arguments are Red, Blue,
Green, and Alpha transparency.)
58
import java.awt. import javax.swing. public
class GlassPanel extends JComponent final
Color trans public GlassPanel ()
this.setOpaque(false) // create nearly black
color with transparency trans new
Color(150,25,25,125) public Dimension
getPreferredSize() return getParent().getPreferr
edSize()
Since were making our own home-grown widget,
and not one found in the API, we have to let the
layout managers know how large this
component wishes to be. We simply return the
size of the parent container--meaning the
GlassPanel have the same size as its parent
container.
59
import java.awt. import javax.swing. public
class GlassPanel extends JComponent final
Color trans public GlassPanel ()
this.setOpaque(false) // create nearly black
color with transparency trans new
Color(150,25,25,125) public Dimension
getPreferredSize() return getParent().getPreferr
edSize() public void
paintComponent(Graphics g) g.setColor(trans) g
.fillRect(0,0,getSize().width, getSize().height)
// GlassPanel
This method defines how the component will look.
Another lecture will explore the details of
drawing in Java. For now, know that this floods
the component with colored pixels.
60
Overview of GlassDemo
GlassDemo (A JFrame subclass )
GlassPanel class
content pane (with JButton)
61
(Demo)
After a press, the glass pane becomes visible,
giving a hazy gauze to the GUI.
62
Design
3.
63
Button Design
  • JButtons are a good example of the Model, View,
    Control paradigm used by Java (borrowed and
    modified from older language Smalltalk)
  • Lets examine the inheritance structure of a
    JButton . . .

public interface javax.swing.ButtonModel extends
ItemSelectable
java.lang.Object --java.awt.Component
--java.awt.Container
--javax.swing.JComponent

--javax.swing.AbstractButton

--javax.swing.JButton
hasA
AbstractButton implements ItemSelectable,
SwingConstants Defines the common behaviors for
the JButton, JToggleButton, JCheckbox, and the
JRadioButton classes.
The ButtonModel provides the state machine for
Button behavior
64
Model, View, Control
  • Let's say you decide to write a program that will
    implement a timer
  • You want to be able to
  • set the time,
  • start and
  • stop the timer
  • You want the timer to show the time counting down
    plus have something exciting happen when time is
    up.
  • You might write a big monolithic program that
    would do all this and be swell...
  • Until someone wanted a version with a different
    display...perhaps some LED's, perhaps a graphical
    widget.
  • Or until someone wanted a version with a
    different control scheme like JButtons

65
MVC
  • Design the timer in three distinct parts (e.g. 3
    classes!)
  • Model This is the heart of the calculation part
    of the timer and is where the data is stored.
    The model might not know anything about the View
    or the Control
  • View The view controls what the user sees (and
    hears). It might run autonomously or be
    controlled by the Control. It might have a
    reference to the Control
  • Control This is what the user interacts with to
    control the timer. It may be a set of keyboard
    commands or a GUI or mechanical pushbuttons. The
    control has references to model and the view.

66
MVC Relationships
View Model m Control c
Model (data)
Controller Model m View v
Clear Interfaces
67
MVC Paradigm
  • The MVC paradigm breaks applications or
    interfaces into three parts the model, the view,
    and the controller.

Users interact with a controller (e.g., buttons),
and make changes to the model (e.g., data), which
is then reflected in the view (e.g., graph).
68
MVC Paradigm, à la Swing
  • Swing uses a simplified version of the MVC
    structure, called the model-delegate

69
MVC Who Cares?
?
Helps us understand complex Swing packages
Guides future package development
Why does it matter?
Allows user customization of model or view,
without rewriting both
(Think of something else need four points)
70
MVC Why You Care
The formal benefits of MVC will be exposed in
subsequent CS classes focused on design and OO
theory. But you should be familiar with MVC now
because Swing widgets use the UI-Delegate
variation of MVC. If you need to change
something about a Swing widget, consider whether
your proposed change affects
The model of a widget (its state, value)
The look of a widget (its UI
delegate) Knowing what you are changing will
help you find where in the API you must look for
useful methods.
71
Questions
72
Danger
4.
73
Cautionary Notes MVC Threads
  • An artifact of the MVC (or model-delegate)
    structure of Swing is the need to avoid separate
    threads updating the model state
  • To avoid a race condition, one should ONLY use
    the event-dispatching queue.

The event-dispatching queue handles repaints, and
dispatches events to GUI component listeners.
Confused by this? The lesson is Dont mix
Threads and Swing unless you know exactly what
youre doing.
74
Cautionary Note Mixing Types
  • Avoid mixing light and heavy weight components.
  • Heavy weights are opaque -- solid rectangular
  • Light weights are transparent, and draw
    themselves on top of the heavyweight container
    they occupy (Frame, Jframe, Panel, etc.)
  • This can frustrate Z-order layering
  • (The slides will violate this principle only to
    make a point.)

Lightweight java.awt.Component
Heavy weight java.awt.Button
What shows up
As designed, and as we coded it
75
Possible Solution Use Timers
We normally think of events as user-driven
actions. But the mere passage of time is an
event that Swing components can observe--all
without the use of additional threads. Java
provides the javax.swing.Timer object--something
of an egg timer that allows one to have an
event fired periodically without user
interaction
delay
Event handler
Timer t new Timer(500, this) t.start()
76
import javax.swing. import java.awt.event. imp
ort java.awt. public class StopWatch extends
JLabel implements ActionListener int count
0 public StopWatch()
super("Elapsed Time 0 secs", JLabel.CENTER)
Timer t new Timer(1000, this) t.start()
public void actionPerformed(ActionEvent
e) this.setText("Elapsed Time "
count " secs") public static void
main (String arg) JFrame f new JFrame()
f.setSize(300,100) f.addWindowListener (new
WindowAdapter() public void
windowClosing(WindowEvent e)
System.exit(0)) StopWatch c new
StopWatch() f.getContentPane()
.setLayout(new BorderLayout())
f.getContentPane() .add(c, BorderLayout.CENTER
) f.show()
77
Questions?
78
Events
Here, we review event handling one more
time. To understand how events work in Java, we
have to look closely at how we use GUIs.
When you interact with a GUI, there are many
events taking place each second. Only a few of
these, however, may actually be delivered to
the application.
79
Events
Java uses a delegation event model found in
many other toolkits. Under the delegation model,
components fire events, which can be caught and
acted on by listeners. A listener is linked to a
component through a registration process. The
delegation event model is contrasted to an event
filtration model where all events are delivered
to target components regardless of whether they
asked for them.
80
General Overview
Recall our first consideration of events, where
our first frame would not close, even when the
end of main() was reached.
We explained this behavior by thinking of our
program as entering an infinite loop when the
graphics are shown. This infinite loop is
actually an event-driven cycle, but we can think
of it as a while (true) structure that
periodically polls for user input.
81
The Real Story
We usually think of our program as a
single, linear set of steps being executed. But
something special happens when we create
graphical objects.
82
The Real Story
When Java sees that youve created a GUI, your
program gets a second set of linear
instructions.
This is actually a separate thread, but dont
worry if thats unclear for now. We can think of
this as a second part of our program than handles
special graphics-related tasks (such as drawing
the window, etc.)
83
Graphics Thread
Both of these threads are your program. You
coded one of the lines of control. Java provides
the other one. That way, things appear to happen
simultaneously--your code executes and the window
gets redrawn, refreshed, etc.
Java quickly switches between your code and the
graphics drawing code, so that both threads
appear to execute at the same time.
84
Dont Panic
Dont worry if this thread stuff is confusing.
Other classes go into this in detail. For our
purposes, we only have to understand that there
are two areas of a graphic program.
1
The code we wrote in main() and other methods
Your Code
Graphics
The code Java provides to handle the graphics
side of things.
2
85
Who Cares?
This model is very important to understand
because as it turns out, when an event
occurs--such as mouse click, it happens in the
graphics side of the model.
Mouse Click occurs
The code trapping this event appears in the
graphics thread
Actually, theres a separate event queue that
handles incoming events. But this is already
complicated enough. Lets just generalize and
imagine that all events arrive in the graphics
side of things.
86
Call backs
Since the event arrived in the graphics half of
our program, we need a way to have it call a
method in our program. This is known as a call
back.
The code trapping this event appears in the
graphics thread
Our event handling code
callback
87
How?
So Java needs to call some event handling code
that we write. The trouble is, how will Java
know what we called out method? We can name them
anything we want, and Java wont necessarily know
what methods handle events.
But Wait! We can use interfaces, right?
88
Event Interfaces
Java uses interfaces as its primary event
handling scheme. If you implement an
event-related interface, Java will know which
methods to call. This is because the contract
nature of interfaces requires all methods to
appear in the implementing class.
public void actionPerformed
(ActionEvent e) // code doing something
This method MUST be there, so Java knows it can
callback to it
89
Why Delegation?
Since any class can implement any interface, we
can have just about any object handle the events.
We can therefore delegate event handling to
this object.
Remember MVC? Some (smart) folks believe you
should organize where the events get
handled. (This is the controller aspect to
MVC.)
M
V
C
90
Why Registration?
We are told that event registration must occur
before event handling will occur. What does this
mean? Well, since we can have any class handle
events, we need to tell Java which object
implements the proper event handling
interface. This registers the component as
being interested in receiving callbacks.
Where to callback?
91
Another example
  • public class DemoFrame extends Frame
  • public DemoFrame( )
  • super (A poor use of inheritance, but
    simple)
  • Handler2 h new Handler2()
  • this.setSize(400,400)
  • this.setLayout(new FlowLayout())
  • Button b new Button (Click me)
  • this.add(b)
  • this.show()
  • // Constructor
  • public static void main(String args)
  • DemoFrame df
  • df new DemoFrame()
  • // main
  • // DemoFrame

92
Another example
  • public class Handler2 implements ActionListener
  • public void actionPerformed(ActionEvent e)
  • System.out.println (Button was clicked)
  • // Handler2

Why doesnt this work?
93
Another example
  • public class DemoFrame extends Frame
  • public DemoFrame( )
  • super (A poor use of inheritance, but
    simple)
  • Handler2 h new Handler2()
  • this.setSize(400,400)
  • this.setLayout(new FlowLayout())
  • Button b new Button (Click me)
  • b.addActionListener(h)
  • this.add(b)
  • this.show()
  • // Constructor
  • public static void main(String args)
  • DemoFrame df
  • df new DemoFrame()
  • // main
  • // DemoFrame

94
Question...
  • We said we had to have a Listener to handle the
    event and it had to be an object. Does it have to
    be a separate object?

95
Another example
  • public class DemoFrame extends Frame implements
    ActionListener
  • public DemoFrame( )
  • super (A poor use of inheritance, but
    simple)
  • Handler2 h new Handler2()
  • this.setSize(400,400)
  • this.setLayout(new FlowLayout())
  • Button b new Button (Click me)
  • b.addActionListener(this)
  • this.add(b)
  • this.show()
  • // Constructor
  • public void actionPerformed(ActionEvent e)
  • System.out.println (Button was clicked)
  • public static void main(String args)
  • DemoFrame df
  • df new DemoFrame()

96
Questions?
97
BSOD
This program has performed an illegal
instruction and will be shutdown. Please shell
out another 200 for a more stable version of
this OS.
98
Just Kidding
Anything can be an event. Including general
protection faults. But for the most part, good
programming dictates that handled events should
come from the following area of input
99
Java Event Handling Strategies
With this basic understanding, we can investigate
the FOUR primary means of event handling in Java
Well not talk about this one
You are 100 guaranteed to have a quiz question
on this
100
Listeners
Strategy No. 1
From the discussion about callbacks, we
noted that interfaces were the primary mechanism
for structuring our event handling. There are
numerous event interfaces we can implement,
roughly divided around categories of events. The
next slide lists many of them. Dont freak out
because there are so many. Well highlight the
most commonly used ones. . .
101
Yikes. So Many Choices
Package java.awt.event features
ActionListener MouseListener MouseMotionListener
AdjustmentListener ComponentListener FocusListene
r ContainerListener ItemListener KeyListener Windo
wListener TextListener
As it turns out, the ActionListener is part of
the semantic event group, even though its an
interface. So lets focus on simple events like
MouseListener...
102
MouseListener
The MouseListener interface has several methods
we have to code
public void mouseClicked(MouseEvent e)
-- a timing-based determination else
the events are processed as
pressed/releases public void
mouseEntered(MouseEvent e) -- entry into
component public void mouseExited(MouseEvent
e) -- exit from component public void
mousePressed(MouseEvent e) -- simply a
press . . . public void mouseReleased(MouseEv
ent e) -- ... the corresponding release
103
import java.awt. import java.awt.event. publi
c class MouseFrame implements MouseListener Colo
r highlight, normal boolean bHighlight
true Frame fr public MouseFrame () fr
new Frame(For demonstration only) highlight
Color.red normal Color.gray frame.setSiz
e(400,400) Button b new Button("Click") b.
addMouseListener(this) fr.setBackground(normal)
fr.setLayout(new FlowLayout()) fr.add(b)
fr.show() public static void
main(String args) new MouseFrame()
To keep it simple, we ignore WindowEvents
Note that when we run this the constructor
will run and terminate
(more)
104
public void mouseReleased(MouseEvent
e) System.out.println ("Changing color") if
(bHighlight) frame.setBackground(highlight)
else frame.setBackground(normal) bHighlight
!bHighlight public void mouseClicked(MouseEv
ent e) public void mouseEntered(MouseEvent e)
public void mouseExited(MouseEvent e)
public void mousePressed(MouseEvent e)
// MouseFrame
click
click
105
Event Listener Summary
We need a class that implements the appropriate
listener type. We need to register a component
as interested in receiving events
addXYZListener ( ltlistener instancegt )
Whatever listener were working with.
E.g. addMouseListener(this) addMouseMotionListe
ner(myEventHandler)
106
Observations
The WindowListener interface required numerous
methods. But only one was important to us. All
the rest were coded as no-op or no operation
methods.
1
2
3
Theres another strategy using adapters, using
inheritance that could have saved us some
trouble...
107
Adapters
Java has built-in classes called event
adapters that implement each of the various
event listeners. But all of these methods are
no-ops.
public class MouseAdapter implements
MouseListener public void
mouseClicked(MouseEvent e) public void
mouseEntered(MouseEvent e) public void
mouseExited(MouseEvent e) public void
mousePressed(MouseEvent e) public void
mouseReleased(MouseEvent e)
WHY?
108
Key to Adapters Inheritance
MouseAdapter
MouseFrame
Why a bunch of no-op methods? Well, if you
subclass the adapter, your class IS-A type of
event listener. And you then only have to
override the one or two methods you care about.
The rest can be inherited as no-ops
109
import java.awt. import java.awt.event. public
class MouseFrame extends MouseAdapter
implements MouseListener
Color highlight, normal boolean bHighlight
true Frame frame public MouseFrame ()
frame new Frame(For demonstration
only) highlight Color.red normal
Color.gray frame.setSize(400,400) Button b
new Button("Click") b.addMouseListener(this) f
rame.setBackground(normal) frame.setLayout(new
FlowLayout()) frame.add(b)
frame.show() public void
mouseClicked(MouseEvent e) public void
mouseEntered(MouseEvent e) public void
mouseExited(MouseEvent e) public void
mousePressed(MouseEvent e)
Parent class takes care of these
110
Example (contd)
public void mouseReleased(MouseEvent
e) System.out.println ("Changing color") if
(bHighlight) frame.setBackground(highlight)
else frame.setBackground(normal) bHighligh
t !bHighlight public static
void main(String args) new MouseFrame()
// MouseFrame
We override the one or two methods we care about
Same behavior less code but we use up our
single inheritance
111
public class MouseAdapter implements
MouseListener public void
mouseClicked(MouseEvent e) public void
mouseEntered(MouseEvent e) public void
mouseExited(MouseEvent e) public void
mousePressed(MouseEvent e) public void
mouseReleased(MouseEvent e)
This comes with Java!
import java.awt. import java.awt.event. public
class MouseFrame extends MouseAdapter implements
MouseListener Color highlight, normal boolean
bHighlight true Frame frame public
MouseFrame () frame new Frame(For
demonstration only) highlight
Color.red normal Color.gray frame.setSize(
400,400) Button b new Button("Click") b.ad
dMouseListener(this) frame.setBackground(normal
) frame.setLayout(new FlowLayout()) frame.ad
d(b) frame.show() public void
mouseReleased(MouseEvent e) System.out.println
("Changing color") if (bHighlight) frame.se
tBackground(highlight) else frame.setBackgro
und(normal) bHighlight !bHighlight publi
c static void main(String args) new
MouseFrame() // MouseFrame
112
Big Picture Time
So far, weve tinkered with different ways of
coding very low-level event handling. But what
if our event handling needs are very
general. Consider this simple dialog box
Theres not much interaction that needs to be
supported. Mouse entry/exit might not be needed
at all.
Are you sure you wish to proceed ?
cancel
ok
113
Semantic Events
Wouldnt it be convenient to abstract all of
these small events into one just-tell-me-when-its
-clicked event?
public void mouseClicked(MouseEvent e) public
void mouseEntered(MouseEvent e) public void
mouseExited(MouseEvent e) public void
mousePressed(MouseEvent e) public void
mouseReleased(MouseEvent e)
M1A1 Abstractor
public void actionPerformed(ActionEvent e)
114
Semantic Events
Strategy No. 3
Semantic events provide a means of
handling events at the component level. That is,
you will not address fine-grained events like
mouse entry and exit. Instead, youll only
receive a callback when the component has
received some type of input event
115
Semantic Events
Semantic Event
Components and Firing Event
ActionEvent
Button (activated)
List (double-clicked)
There are numerous event handlers for low-level
events associated with these widgets.
MenuItem (selected)
TextField (typed)
AdjustmentEvent
Scrollbar (moved)
ItemEvent
Checkbox (toggled) CheckboxMenuItem
(selected) Choice (selected) List (selected)
TextEvent
TextComponent (text changes)
Note ALL input is sent into one of these FOUR
categories.
116
Example
import java.awt. import java.awt.event. public
class MouseFrame extends Frame
implements ActionListener Color
highlight, normal boolean bHighlight
true public MouseFrame () highlight
Color.red normal Color.gray this.setSize(400
,400) Button b new Button("Click") b.addActi
onListener(this) this.setBackground(normal) th
is.setLayout(new FlowLayout()) this.add(b) thi
s.show()
117
Example (contd)
public void actionPerformed(ActionEvent
e) System.out.println ("Changing color") if
(bHighlight) this.setBackground(highlight)
else this.setBackground(normal) bHighlight
!bHighlight public static void
main(String args) new MouseFrame()
// MouseFrame
We therefore lose the ability to handle very
fine-grained events (e.g., mouse entry/exit).
But that might be acceptable for certain
applications.
118
(non) Option 4 JDK 1.02 Events
  • An earlier version of Java used boolean return
    values to indicate consumption of events.
    Events were delivered to components whether or
    not they registered for 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.
  • More common use some browsers only support JDK
    1.02--a very early version of Java that uses this
    model. Professional applet developers still use
    this technique. Many browsers are now supporting
    the JDK 1.1 event model.

119
Event 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
120
Debugging 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!

121
Debugging 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.

System.out.println is still your friend...
122
Events A Short Example
To compare the three event handling techniques,
lets see a brief example how all three might
work on a common problem.
Goal Create a simple Frame that holds a
TextArea and Button. The Button toggles the
ability to edit the TextArea
The Panel holding the Button and TextArea is
placed in a Frame subclass, which handles its own
disposal
TEXT AREA
BUTTON
Panel subclass
123
import java.awt. import java.awt.event. public
class MyFrame extends Frame implements
WindowListener public static final int iWidth
300, iHeight 500 public MyFrame()
this.setSize(iWidth, iHeight) this.addWindo
wListener(this) BorderLayout border new
BorderLayout() this.setLayout(border) publ
ic void windowClosing (WindowEvent e)
e.getWindow().setVisible(false) e.getWindow
().dispose() System.exit(0) public void
windowActivated(WindowEvent e) public void
windowClosed(WindowEvent e) public void
windowDeactivated(WindowEvent e) public void
windowDeiconified(WindowEvent e) public void
windowIconified(WindowEvent e) public void
windowOpened(WindowEvent e) // class MyFrame
Constructor
WindowListener
Frames are not self-disposing! (Setting Frame
invisible first eliminate flicker.)
124
Advanced featureAnonymous Inner Class used
as a short cut. For your code, use listeners
import java.awt. import java.awt.event. public
class MyFrame extends Frame public static
final int iWidth 300, iHeight 500
public MyFrame() this.setSize(iWidth,
iHeight) this.addWindowListener (new
WindowAdapter() public void
windowClosing (WindowEvent e)
e.getWindow().setVisible(false) e.getWind
ow().dispose() System.exit(0)
) BorderLayout border new BorderLayout() th
is.setLayout(border) // class MyFrame
Frames are not self-disposing! (Setting Frame
invisible first eliminate flicker.)
125
import java.awt. public class Driver
public static void main (String arg)
Notepad note new Notepad() MyFrame f
new MyFrame() f.add(note,
BorderLayout.CENTER) f.show()
//main //class Driver
A simple driver. Notice that so far, weve
abstracted the Frame subclass into something
very generic and reusable--ITS NOT JUST TIED TO
THIS PROGRAM!
126
Variation 1 Listener Events (MouseListener)
import java.awt. import java.awt.event. class
Notepad extends Panel implements MouseListener
Button toggle TextArea scratch
boolean bWritable public Notepad()
super("Wasted inheritance") this.setLayout
(new BorderLayout()) scratch new
TextArea(20,20) Panel buttonPanel new
Panel() toggle new Button ("Freeze/Unfreeze")
buttonPanel.add(toggle) add(scratch,
BorderLayout.CENTER) add(buttonPanel,
BorderLayout.SOUTH) toggle.addMouseListener(this
) bWritable false // constructor
The Driver and MyFrame classes were generic
enough to work with any version of this example.
Here, however, we need to create a specific
event handler.
127
/ . . . Continued from class Notepad extends
Panel implements MouseListener . . .
/ public void setWritable(boolean
bWritable) this.bWritable bWritable
//setWritable public boolean getWritable()
return bWritable //getWritable
public TextArea getTextArea() return
scratch //getTextArea public void
mousePressed(MouseEvent e) getTextArea().setEna
bled(getWritable()) setWritable(!getWritable())
//mousePressed public void
mouseReleased(MouseEvent e) public void
mouseClicked(MouseEvent e) public void
mouseEntered(MouseEvent e) public void
mouseExited(MouseEvent e) //class Notepad
Implement the method one needs the rest are
no-ops
128
Driver main Notepad note MyFrame f
Notepad extends Panel Button toggle
TextArea scratch boolean bWritable
129
Variation 2 Adapter Events (MouseAdapter)
import java.awt. import java.awt.event. class
Notepad extends Panel / NOTE NO INTERFACE!
/ Button toggle TextArea scratch
boolean bWritable public void
setWritable(boolean bWritable) this.bWritable
bWritable //setWritable public boolean
getWritable() return bWritable
//getWritable public TextArea
getTextArea() return scratch
//getTextArea
130
/ . . . Continued from class Notepad extends
Panel / public Notepad() super()
this.setLayout (new BorderLayout()) scratch
new TextArea(20,20) Panel buttonPanel new
Panel() toggle new Button ("Freeze/Unfreeze")
buttonPanel.add(toggle) add(scratch,
BorderLayout.CENTER) add(buttonPanel,
BorderLayout.SOUTH) toggle.addMouseListener(new
MouseAdapter() public void
mousePressed(MouseEvent e)
getTextArea().setEnabled(getWritable())
setWritable(!getWritable()) )/
end of anonymous inner class / bWritable
false // constructor
Note use of anonymous inner class.
131
Variation 3 Another Way!
  • import java.awt.
  • import java.awt.event.
  • public class AnotherHandler extends MouseAdapter
  • Notepad np
  • public AnotherHandler(Notepad np)
  • this.np np
  • // Constructor
  • public void mousePressed(MouseEvent e)
  • np.getTextArea().setEnabled(np.getWritable())
  • np.setWritable(!np.getWritable())
  • // AnotherHandler

132
Variation 3 Another Way
import java.awt. import java.awt.event. class
Notepad extends Panel / NOTE NO INTERFACE!
/ Button toggle TextArea scratch
boolean bWritable public void
setWritable(boolean bWritable) this.bWritable
bWritable //setWritable public boolean
getWritable() return bWritable
//getWritable public TextArea
getTextArea() return scratch
//getTextArea
133
/ . . . Continued from "class Notepad extends
Panel" / public Notepad() super()
this.setLayout (new BorderLayout()) scratch
new TextArea(20,20) Panel buttonPanel new
Panel() toggle new Button ("Freeze/Unfreeze")
buttonPanel.add(toggle) add(scratch,
BorderLayout.CENTER) add(buttonPanel,
BorderLayout.SOUTH) AnotherHandler ah new
AnotherHandler(this) toggle.addMouseListener(ah)
bWritable false // constructor
134
Variation 4 Semantic Events (ActionListener)
import java.awt. import java.awt.event. class
Notepad extends Panel implements ActionListener
Button toggle TextArea scratch
boolean bWritable public Notepad() super()
this.setLayout (new BorderLayout()) scratch
new TextArea(20,20) Panel buttonPanel new
Panel() toggle new Button ("Freeze/Unfreeze")
buttonPanel.add(toggle) add(scratch,
BorderLayout.CENTER) add(buttonPanel,
BorderLayout.SOUTH) toggle.addActionListener(thi
s) bWritable false // constructor
135
/ . . . Continued from "class Notepad extends
Panel implements ActionListener" . .
. / public void setWritable(boolean
bWritable) this.bWritable bWritable
//setWritable public boolean
getWritable() return bWritable
//getWritable public TextArea getTextArea()
return scratch //getTextArea public
void actionPerformed (ActionEvent e)
getTextArea().setEnabled(getWritable()) setWr
itable(!getWritable()) //actionPerformed /
/class Notepad
136
Event Handlers Final Review
This simple example shows that sometimes,
semantic event handlers perform the task
perfectly. In the drawing applet example, the
semantic event handler was unable to offer help.
In this example, it works perfectly, and was
easier to follow and implement. Note that a few
of the examples in this notepad demonstration
used anonymous inner classes. You will not be
required to use anonymous inner classes in CS2
however, they are used a lot and if y
Write a Comment
User Comments (0)
About PowerShow.com