|
|
< Day Day Up > |
|
5.8 TimersTimers allow an arbitrary block of code to be run after waiting for a timeout interval. Timers are not implemented as interrupts. They are executed in the user interface thread like other operating system events. In fact, on some platforms, they are implemented as operating system events, coming in through the event queue like any other event. In any case, timers run before syncExec() and asyncExec() blocks, which run only when the user interface is idle. The following method, on class Display, is used to create a timer.
This code fragment creates a timer to execute a runnable after waiting for 2 seconds.
display.timerExec(2000, new Runnable() {
public void run() {
System.out.println("Once, after 2 seconds.");
}
});
Timers run only once. To run a timer repeatedly, queue the same runnable again, using the same time interval. This code fragment uses a timer to execute a runnable every 2 seconds.
display.timerExec(2000, new Runnable() {
public void run() {
System.out.println("Every 2 seconds.");
display.timerExec(2000, this);
}
});
To change the timeout period for a pending timer, timerExec() is called with the new interval and the original runnable. The following code fragment first sets a timer to run after 2 seconds, then resets the timer to run after 5 seconds, causing the timer to run once, after 5 seconds. display.timerExec(2000, timer); display.timerExec(5000, timer); As you might expect, a pending timer can be forced to run right away by changing the timeout value to zero. A pending timer can also be removed by using a negative timeout interval. The following code fragment removes a pending timer. display.timerExec(-1, timer); 5.8.1 Detecting Inactivity in the Event LoopThe following example uses a timer to detect 3 seconds of inactivity in the event loop.
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.pack();
shell.open();
final int TIME_OUT = 3000;
Runnable runnable = new Runnable() {
public void run() {
System.out.println(
"Idle for "
+ (TIME_OUT / 1000)
+ " seconds");
}
};
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.timerExec(TIME_OUT, runnable);
display.sleep();
display.readAndDispatch();
display.timerExec(-1, runnable);
}
}
display.dispose();
}
Instead of simply sleeping right away when readAndDispatch() returns false, the example code first adds a timer. This ensures that sleep() will wake up after suspending execution for no more than 3 seconds. When sleep() wakes up, two things could have happened. Either the timer expired or an operating system event became available. To determine which occurred, readAndDispatch() is called. If the timer expired, readAndDispatch() executes the timer, and the system was idle for 3 seconds. Otherwise, readAndDispatch() dispatches the operating system event, and the system was not idle. In any case, the timer is removed so that it will not execute erroneously later on. It is not an error to attempt to remove a timer that has already expired, so no check for this case is necessary in the code. There are many reasons why events are sent to an application. Even when the user is not clicking, moving the mouse, or typing on the keyboard, the event loop may not be idle. For example, another part of the program may register a timer. Even the operating system itself may generate events at arbitrary intervals.[8] A better way to detect inactivity is to monitor the keyboard.
5.8.2 Detecting Inactivity in the KeyboardThe following example uses a timer to detect inactivity in the keyboard after waiting 3 seconds.
public static void main(String[] args) {
final Display display = new Display();
Shell shell = new Shell(display);
shell.pack();
shell.open();
final int TIME_OUT = 3000;
final Runnable runnable = new Runnable() {
public void run() {
System.out.println(
"Idle for "
+ (TIME_OUT / 1000)
+ " seconds");
display.timerExec(TIME_OUT, this);
}
};
display.addFilter(SWT.KeyDown, new Listener() {
public void handleEvent (Event event) {
display.timerExec(TIME_OUT, runnable);
}
});
display.timerExec(TIME_OUT, runnable);
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
The code works by adding the same timer (that fires once every 3 seconds) each time a key is pressed. Because the timer is added again each time, when the user types a key, the period is reset to be 3 seconds from that time. If 3 seconds pass without any keyboard events occurring, the timer will fire, then reschedule itself to run 3 seconds later. This causes the timer to fire every time there is a 3-second period of no keyboard activity. If you need to detect only when it has been 3 seconds since the last time a key was pressed, you can leave out the display.timerExec(TIME_OUT, this) call in the body of the timer. Similar code could be written to check for mouse events or any other combination of events. |
|
|
< Day Day Up > |
|