import java.awt.*; import java.awt.event.*; /** (C) 2000 Charles Consulting, LLC
Button which repeats action if held down. Note that this class will start a daemon Thread when pressed. The thread is normally waiting. It will terminate up to 'detachCheck' milliseconds after Button is removed from its parent.
The ActionEvent sent will contain, as a string, the number of cycles the button has been held down for. */ public class HolddownButton extends Button { /** millisecond delay between processing */ public static final int buttonDelay = 500; /** how to to wait between checks to see if button was detached */ public static final int detachCheck = 600000; //ten minutes /** current state of button */ private boolean isDown; /** thread to process multiple events if button held down */ private TimerThread thread; /** constructor */ public HolddownButton( ) { super( ); addMouseListener( new MouseAdapter( ) { public void mousePressed(MouseEvent e) { setDown(true); } public void mouseReleased(MouseEvent e) { setDown(false); } public void mouseExited(MouseEvent e) { setDown(false); } }); } private final synchronized void setDown(boolean d) { isDown = d; if (isDown) { if (thread == null) { thread = new TimerThread(); thread.setDaemon(true); thread.start( ); } else notify( ); } } /** allow inner class to access protected method */ private final void forwardEvent(AWTEvent e) { super.processEvent(e); } private class TimerThread extends Thread { /** threaded function. Sends event while button held down; exits when button removed from parent */ public void run( ) { while (getParent( ) != null) { try { sleep(buttonDelay); } catch (InterruptedException e) { continue;} synchronized(HolddownButton.this) { while (!isDown && getParent( ) != null) try { HolddownButton.this.wait(detachCheck); } catch (InterruptedException e) { continue; } } ActionEvent ev = new ActionEvent(HolddownButton.this, ActionEvent.ACTION_PERFORMED,""); forwardEvent(ev); } thread = null; } } }