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;
}
}
}