/* * Idle.java * * Created on February 19, 2003, 10:32 PM */ import java.awt.event.*; import java.awt.*; import java.util.*; /** A class which is capable of firing an event when the system * is idle (no input events in > MASK milliseconds). * The idle event is fired only once per idle period. The only * interesting methods are the static addlistener() * and removeListener() methods.

Once a listener * is added, a daemon timer is started and an AWTEventListener registered * for input events. For each input event a counter is incremented. * When the timer fires, the current value is compared with the last * known count. If they are the same, this is noted, and if they are * still the same the next time the timer fires, listeners are notified * that the system is idle.

This means that the minimum time that * listeners will be notified is when the system has been idle at least * DELAY * 2 milliseconds.

This class can be used to fire * periodic events such as file system update checks which should be * periodic but which should not occur more than once when the system is truly * idle because they can trigger disk paging. * * @author Tim Boudreau * @version 1.0 */ public final class Idle extends TimerTask implements AWTEventListener { private transient java.util.ArrayList idleListenerList; private int count=0; private int lastCount=-1; private boolean lastWasEqual=false; private boolean idling=false; private Timer timer=null; public static final long DELAY=10000; private static final long MASK = AWTEvent.INPUT_METHOD_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK; private static final boolean VERBOSE = Boolean.getBoolean ("netbeans.verbose.idle"); //NOI18N private static final boolean GC_ON_IDLE = Boolean.getBoolean ("netbeans.idle.gc"); //NOI18N /** Creates a new instance of Idle */ private Idle() { } /** Start the timer and add the AWT listener */ private void attach () { timer = new Timer (true); timer.schedule(this, DELAY, DELAY); Toolkit.getDefaultToolkit().addAWTEventListener(this, MASK); } /** Stop the timer, remove the listener and cause this instance * to become unreferenced */ private void detach () { timer.cancel(); Toolkit.getDefaultToolkit().removeAWTEventListener (this); instance = null; } /** Public as a side effect of implementing AWTEventListener */ public void eventDispatched(AWTEvent event) { count++; if (VERBOSE) System.out.println("EVENT: " + event); //NOI18N } /** Public as a side effect of implementing TimerTask */ public void run() { if (VERBOSE) System.out.println( "Checking idle at " + System.currentTimeMillis()); //NOI18N if (count == lastCount) { if (lastWasEqual) { if (!idling) { fireIdle(); idling = true; } } else { lastWasEqual = true; if (VERBOSE) System.out.println( "If no events, next timer event will fire idle"); //NOI18N return; } } else { lastWasEqual = false; idling=false; lastCount = count; } } /** Registers IdleListener to receive events. * @param listener The listener to register.*/ private synchronized void addIdleListener(IdleListener listener) { if (idleListenerList == null ) { idleListenerList = new java.util.ArrayList(); } idleListenerList.add(listener); if (idleListenerList.size() == 1) { attach(); } } /** Removes IdleListener from the list of listeners. * @param listener The listener to remove.*/ private synchronized void removeIdleListener(IdleListener listener) { if (idleListenerList != null ) { idleListenerList.remove(listener); if (idleListenerList.size() == 0) { detach(); } } } /** Notify listeners that the system is now idle */ private void fireIdle () { java.util.ArrayList list; synchronized (this) { if (idleListenerList == null) return; list = (java.util.ArrayList)idleListenerList.clone(); } for (int i = 0; i < list.size(); i++) { ((Idle.IdleListener)list.get(i)).idle(); } //listeners should not do this, it always should come last if (GC_ON_IDLE) System.gc(); } public interface IdleListener extends EventListener { void idle(); } private static Idle instance=null; /** Add an idle listener to listen for idle events. */ public static void addListener(IdleListener listener) { if (instance == null) { instance = new Idle(); } instance.addIdleListener (listener); } /** Remove an idle listener to listen for idle events. */ public static void removeListener(IdleListener listener) { instance.removeIdleListener (listener); } /** Test execution - find three idle cycles & trigger gc on idle */ public static void main (String[] args) { IdleListener listener = new IdleListener () { int count=0; public void idle() { System.out.println("Idling at " + System.currentTimeMillis()); //NOI18N count++; if (count == 3) { Idle.removeListener (this); System.exit (0); } } }; Idle.addListener (listener); } }