Title: Graphical User Interface GUI Programming II
1Graphical User Interface (GUI) Programming II
2Lecture Objectives
- Understand the Event-Handling Processes in Java
3Caution Note!!!
- This lecture presentation contains a number of
"hidden" slides. Feel free to read, study and
learn from them on your own!!!
4Outline for Today's Fun
- Events
- What is an event?
- Simple (?) Example
- Swing Components
- JFrames
- JComponents
- An example
- Swing Component Design (MVC/UI-Delegate??)
5Events
- 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"
6Events (Contd)
- 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.
7Code from the Past Remember???
- import java.awt.
- public class HelloGUI
- public static void main (String args)
- 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
8What didn't work???
Code from the Past Remember???
9Making It Work (MIT Approach)!
- 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.
10Making It Work (MIT Approach)!
- 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?
11Interfaces Back to School!
- // 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)
12So we could write a class as shown below
Using Event Interfaces
- Outline
- Import
- Class definition
- Implementation
- Dummy (lazy) implementation
- 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)
13Using Event Interfaces (Contd)
- 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.
14Event Handler Registration
- import java.awt.
- public class HelloGUI
- public static void main (String args)
- 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
15Demonstration
Class Pool
class HelloGUI main Frame f Handler
h
class Frame
class Handler
Interface WindowListener
Frame Instance
Handler Instance
16Event Handling 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.
17Todays First Wisdom
- Very important that you understand this simple
example to understand the concepts that follow.
18Potential 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 Java API.
- Lecture/Instructor/Lab/WebCT/Classmates/Friends.
- Try yourself and experience the excitement!
19Potential Points of Confusion (Contd)
- What about all those other window things (e.g.
windowActivated) - We actually did implement them (with empty
bodies) Lazy or dummy implementation! - We said Don't do anything!
20Outline for Today's Fun Reminder
- Events
- What is an event?
- Simple (?) Example
- Swing Components
- JFrames
- JComponents
- An example
- Swing Component Design (MVC/UI-Delegate)
21A Call from the Past!
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.
22Swing Suns Response to Microsoft?
- 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 . . .
23Welcome to JFC/Swing Planet
- Now it gets interesting . . .
24Historical 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)
25Fixing AWT Problems
- 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!
26Introducing Swing/JFC
- Sun addressed these problems by producing Java
Foundation Classes (JFC) i.e., 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!
27Swing 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
28Overview 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
29Overview 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
30Short Examples
1.
31Short 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.
32Hello 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!!!
33Whats 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.
34Widget 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.
35Cool 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
36Why 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 . . .
37A JFrame Autopsy
The Pop Tart / Sandwich Duality
38JFrame 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
39JRootPane The Content Pane
40JRootPane 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()
41JFrame 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(WindowCo
nstants.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.
42JComponent 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.
43Jcomponent (Contd)
44Demo 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
45Demo A GlassPane Example (Contd)
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
46Demo A GlassPane Example (Contd)
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.)
47Demo A GlassPane Example (Contd)
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()
48Demo A GlassPane Example (Contd)
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
49Demo A GlassPane Example (Contd)
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.
50Demo A GlassPane Example (Contd)
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. . .
51Demo A GlassPane Example (Contd)
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.
52Example Output
After a press, the glass pane becomes visible.
53Events
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.
54Events (Contd)
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.
55Events 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.
56The 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.
57The Real Story (Contd)
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.)
58The Real Story (Contd)
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.
59The Real Story 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
60The Real Story 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?
61Event 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
62Why 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?
63An 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
64Another Example
- public class Handler2 implements ActionListener
- public void actionPerformed(ActionEvent e)
- System.out.println (Button was clicked)
-
- // Handler2
Why doesnt this work?
65Another Example (Contd)
- public class DemoFrame extends JFrame
- public DemoFrame( )
- super (A poor use of inheritance, but
simple) - Handler2 h new Handler2()
- this.setSize(400,400)
- this.setLayout(new FlowLayout())
- JButton b new JButton (Click me)
- b.addActionListener(h)
- add(b)
- show()
- // Constructor
- public static void main(String args)
- DemoFrame df
- df new DemoFrame()
- // main
- // DemoFrame
66Question???
- 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?
67Another 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()
- // main
- // DemoFrame
68Is There Any Other Event There?
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
a
Mouse events
Keyboard events
b
c
Timing events
Other user action inputs
d
69Java 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
70Listeners
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. . .
71Listeners 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...
72MouseListener
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
73MouseListener An Example
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
74MouseListener An Example (Contd)
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
75Event 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)
76Event Listener 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...
77Adapters
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???
78Key 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
79Event Adapters (Contd)
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
80Event Adapters (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
81public 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
82Big 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
83Event Handling Options How to Decide?
Costs Benefits
Event Listeners (interfaces) Event
Adapters (inheritance)
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
84Debugging 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!
85Debugging Event Handlers (Contd)
- 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...
86Events 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
87Events A Short Example (Contd)
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.)
88Events A Short Example (Contd)
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.)
89Events A Short Example (Contd)
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