| Home > Core Java FAQ
> Event Handling FAQ |
| Event
Handling |
| Events
in 1.0 (11) * Event Classes,
Listeners, and Methods (08) * Semantic
Events (04) * Low-Level Events (04) |
| |
|
Q . My frame doesn't close when I click on Quit/Close in the main menu-- how do I fix this using the JDK 1.1?
|
Ans :
Define windowClosing
in a WindowListener object and use addWindowListener
to register that listener to the frame.
Clicking
on Quit/Close (depending on the native windowing system) generates
a window-destroy event, which your application needs to catch and
handle appropriately. How you catch the event differs between the
JDK 1.0.2 and 1.1, as will be discussed, but the code needed to
respond to the event is essentially the same. You use the Frame
class's dispose method to dispose of the frame along
with any resources connected to it. Additionally, if you want the
frame's closing to terminate the application, you can call System's
exit method.
In the JDK 1.1, you catch the
window-destroy event by attaching an appropriate WindowListener
object to the frame. The key method to define is windowClosing:
/* using JDK 1.1: */
class Example extends java.applet.Applet {
/** An inner class that closes the window and quits the app. */
class WindowCloser extends WindowAdapter {
public void windowClosing(WindowEvent e) {
e.getWindow().dispose();
}
}
public void init() {
Frame f = new Frame("Closeable Frame");
f.addWindowListener(new WindowCloser());
// ...
}
|
|
Q . Is there an event type that signals when a window is resized?
|
Ans :
There is no
event in the JDK 1.0.2 for window resizing, but the JDK 1.1
includes notification of window resizing by means of ComponentEvent.
The JDK 1.0.2 lacks a specific event
type for window resizing. Some programmers noticed that Event.WINDOW_MOVED
catches window resize events on Solaris, but this is a
platform-specific coincidence that should not be relied on.
The JDK 1.1 event model in the AWT
provides a general event type for signaling the resizing and
relocating of any component, not just windows. You can detect
window size and location changes by catching the component-resize
and component-move events for your window. To do this, attach an
appropriate ComponentListener object to the window(s)
you wish to receive events from. The following simple class
illustrates how:
public class Example {
class ComponentReporter extends ComponentAdapter {
public void componentMoved(ComponentEvent e) { /* ... */ }
public void componentResized(ComponentEvent e) { /* ... */ }
}
ComponentListener reporter = new ComponentReporter();
Frame mainFrame = new Frame("Resize and Move Events");
public void init() {
mainFrame.addComponentListener(reporter);
// ...
}
// ...
}
|
|
Q . How do I handle events for function keys, arrow keys, and so on in the JDK 1.1 event model?
|
Ans :
Attach a KeyListener
object to the event source and check for the specific key types
you want to catch.
The JDK 1.1 event model divides key
events into two types, as shown in Table 7.6. Lower-level events
directly convey the user's actions on the keyboard, and
higher-level events convey the input characters resulting from the
user's typing.
Table
: Key Events—JDK 1.1
| Lower-level,
key action |
keyPressed(KeyEvent
e) |
| keyReleased(KeyEvent
e) |
| Higher-level,
key input |
keyTyped(KeyEvent
e) |
For input
characters directly supported by the user's keyboard, a single keyTyped
event corresponds to a keyPressed event followed by a
keyReleased event. For other input characters, more
complex mappings from key actions are possible.
Function keys, arrow keys, and so on
are action keys. The AWT reports any key presses or
releases that occur on action keys, but it never generates key
input events from the action keys. Therefore, to catch action key
events, you need to supply a KeyListener object that
handles the low-level events with its keyPressed
and/or keyReleased methods.
Once you've caught the event, you
can query the KeyEvent object to find out more
specifically which key triggered the event. KeyEvent's
isActionKey method is useful for making the
high-level split between action keys and content keys. To make
finer distinctions among action keys, invoke getKeyCode
on the event object, and test that value against the KeyEvent
values shown in Table.
Table
: Key Constants in KeyEvent—JDK 1.1
| navigation
keys |
HOME,
END, PGUP, PGDN, UP,
DOWN, LEFT, RIGHT |
| function
keys |
F1,
F2, F3, F4, F5,
F6, 7, F8, F9,
F10, F11, F12 |
| other
action-type keys |
PRINT_SCREEN,
SCROLL_LOCK, CAPS_LOCK, NUM_LOCK,
PAUSE, INSERT |
The
following code excerpt shows a Canvas subclass that
cares only about processing action keys, and that beeps the user
as a reminder that content keys are not expected:
/* using JDK 1.1: */
class ExampleCanvas extends Canvas {
/* An inner class listener for key pressed events. */
class KeyTracker extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if (e.isActionKey()) {
drawXOR = e.isControlDown();
switch (e.getKeyCode()) {
case KeyEvent.F1:
fullRepaint = true;
break;
case KeyEvent.LEFT:
translatePoint(-stepSize, 0);
break;
// ...
default:
break;
}
repaint();
return;
}
/* Beep for any non-action key presses */
getToolkit().beep();
}
}
static int stepSize = 4;
boolean drawXOR = false;
boolean fullRepaint = true;
public ExampleCanvas() {
addKeyListener(new KeyTracker());
}
void translatePoint(int dx, int dy) { /* ... */ }
// ...
}
|
|
Q . How does the JDK 1.1 distinguish between mouse clicks made with different buttons on a two- or three-button mouse?
|
Ans :
The JDK 1.1
MouseEvent
class uses the modifiers field in the event object to distinguish
between different mouse buttons; the InputEvent
class provides modifier masks with which you can test the
modifiers data.
Like
the JDK 1.0.2, the JDK 1.1 generates mouse events for all mouse
clicks on a multibutton mouse. The event methods are the same
regardless of which button is used, but the MouseEvent
object carries the distinction in its modifiers data. You can
determine which button was used with the help of modifier masks in
the InputEvent class (superclass of both MouseEvent
and KeyEvent):
/* in InputEvent.java, JDK 1.1: */
public static final int BUTTON1_MASK = 1 << 4;
public static final int BUTTON2_MASK = 1 << 5;
public static final int BUTTON3_MASK = 1 << 6;
Below
is a sample MouseListener that reports which mouse
button was pressed, together with which modifier keys were down at
the time:
class MouseReporter extends MouseAdapter {
public void mousePressed(MouseEvent e) {
int mod = e.getModifiers();
if ((mod & InputEvent.BUTTON3_MASK) != 0) {
System.out.print("button 3 ");
} else if ((mod & InputEvent.BUTTON2_MASK) != 0) {
System.out.print("button 2 ");
} else {
System.out.print("button 1 ");
}
System.out.println("pressed, "
+ (mod == 0 ? "no modifiers "
: "modifiers = ")
+ (e.isAltDown() ? "alt " : "")
+ (e.isMetaDown() ? "meta " : "")
+ (e.isShiftDown() ? "shift " : "")
+ (e.isControlDown() ? "control "
: ""));
}
}
|
|
|
|