Você está na página 1de 23

UID Event Handling and Listeners

Event handling and listeners


What is an event?
user actions and context event sources and listeners

Why should my programs be eventdriven?


User interaction with the GUI

Some typical component events and listeners


Act that results in event User clicks a button, presses return while typing in a text field, or chooses a menu item User closes a window User presses a mouse button while the cursor is over a component Component becomes visible Component gets the keyboard focus Table or list selection changes Listener ActionListener

WindowListener MouseListener

User moves the mouse over a component MouseMotionListener ComponentListener FocusListener ListSelectionListener

Implementing listeners (1)


Three key bits of code
1) add interface 2) register 3) handle

Components can have multiple listeners

A simple JButton ActionListener

Implementing listeners (2)


public class myClass implements ActionListener { // where setting up occurs (e.g. constructor) JButton button = new JButton(I am a button); button.addActionListener(this); public void actionPerformed(ActionEvent e) { // respond to event } // end response method } // end class

Types of event listeners (1)


Global component listeners
may be used for any Swing components Types
ComponentListener (changes in size, position, visibility) FocusListener (whether ability for keyboard input) KeyListener (key press events, only with focus) MouseListener (clicks and movement into/out of component area) MouseMotionListener (changes in position over component)

Types of event listeners (2)


Component-specific listeners
relevant to specific components actions Types
ActionListener CaretListener ChangeListener DocumentListener ItemListener ListSelectionListener WindowListener etc.

See:
http://java.sun.com/docs/books/tutorial/uiswing/events/eventsandcomponents.html

Working with event listeners

Getting event information Low-level events Semantic events Adapters for event handling Inner classes for event handling

Getting event information


EventObject class - use sub classes of this to determine whats happened. Get the firing object with getSource(); Actual event classes sometimes have specific types
e.g. the ComponentListener uses a sub-class of EventObject : ComponentEvent that has getComponent();

Event classes may define methods that return more information


e.g. ActionEvent has a method for getting modifiers (Shift, Alt, Ctrl)

Low-level and semantic events (1)


Low-level events - window-system level
e.g. mouse, key, component, container, focus, window trigger component-independent

Semantic events
everything else! e.g. action, item, list selection trigger can differ by component
e.g. button click and textfield return action events

Low-level and semantic events (2)


Listen for semantic events whenever possible
Gives robust and portable code
eg Button - listen for action event rather than mouse event. Means that button responds to keyboard shortcuts.

Compound components
eg combo box - no real way of guaranteeing low level listeners on all look and feel specific components used to form the compound component.

Adapters for event handling (1)


Classes which implement listener interfaces must implement all listener methods
e.g. MouseListener has 5 methods: mouseClicked, mouseReleased, mousePressed, mouseEntered, mouseExited

This leads to cluttered code


Say you only want mouseClicked to do something then all others have to be implemented but empty

Alternative.

Adapters for event handling (2)


... is to extend a MouseAdapter class
inherits empty definitions of all five mouseListener methods. Eg:
public class MyClass extends MouseAdapter { ...
someObject.addMouseListener(this); ... public void mouseClicked(MouseEvent e) { //Event handler implementation goes here... } }

Inner classes for event handling (1)


Dont want to / cant inherit from an adapter class?
theres no multiple inheritance in Java
eg cant extend JPanel AND MouseAdapter

Solution: use an inner class


public class MyClass extends JPanel { anObject.addMouseListener(new myAdapter()); class myAdapter extends MouseAdapter { public void mouseClicked(MouseEvent e) { // blah } // end mouseClicked } // end inner class } // end MyClass

Inner classes for event handling (2)


Anonymous classes used to simplify code good when only 1 instance will ever be needed
public class MyClass extends JPanel { ... someObject.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { //Event handler implementation goes here } }); ... }

Threads and Swing (1)


Why use them?
Improved perceived performance Can remove time consuming task from event thread to keep GUI responsive Initialisation of program so GUI appears faster

Potential problems
Deadlock the application if access any realised swing components from non event threads.

Threads and Swing (2)


Remember the rule:
Once a Swing component has been realised, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.

If code does not need to be in event thread then:


public void actionPerformed(ActionEvent e) {
final SwingWorker worker = new SwingWorker() { public Object construct() { //---code that might take a while to execute is here... return someValue; } }; worker.start(); //required for SwingWorker 3 }

Threads and Swing (3)


invokeLater()
requests that event thread runs certain code can be called from any thread code goes in run method of Runable object returns immediately without waiting for event thread to execute code.
Runnable updateAComponent = new Runnable() { public void run() {component.doSomething(); } }; SwingUtilities.invokeLater(updateAComponent);

Threads and Swing (4)


invokeAndWait()
identical to invokeLater() except doesnt return till event thread has finished executing the code. Should use this if possible - less chance of deadlock.
void showHelloThereDialog() throws Exception { Runnable showModalDialog = new Runnable() { public void run() { JOptionPane.showMessageDialog(myMainFrame, "Hello There"); } }; SwingUtilities.invokeAndWait(showModalDialog); }

Summary - but not the end...


Implementing event listeners Types of event listeners Handling event listeners
getting event information low-level and semantic events adapters inner classes - named and anonymous

Threads

What Covered So Far?


What is Swing? Containers
Frames Dialogs (applets)

Components
Loads to choose from

Layout Managers
Educated Trial and Error

Events and User Interaction

A simple Swing program


Uses components in containers Lays components out correctly Listens for events An example:
SwingExample.java (revisited)
Code on Course Website

A (Slightly) More Complex Swing program


Uses components in containers (again) Lays components out correctly (again - but more complex) Listens for events - Multiple listeners Another example:
SwingExample2.java

Você também pode gostar