/**************************************************************************
* Copyright (c) 2007, 2008 Gregory Jordan
*
* This file is part of PhyloWidget.
*
* PhyloWidget is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* PhyloWidget is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PhyloWidget. If not, see <http://www.gnu.org/licenses/>.
*/
package org.andrewberman.ui;
import java.util.ArrayList;
/**
* The <code>Blinker</code> object is a simple thread that simply blinks on and off,
* in a (hopefully) fairly computationally cheap fashion. It is used by the <code>
* TextField</code> class to draw the caret on the screen.
* @author Greg
* @see org.andrewberman.ui.TextField
*/
public class Blinker extends Thread
{
public static Blinker instance;
private int delay;
public boolean isOn;
public boolean interrupted;
private ArrayList listeners;
private Blinker(int delay)
{
this.delay = delay;
listeners = new ArrayList(1);
isOn = true;
interrupted = false;
}
/**
* Retrieves the current Blinker instance. Multiple TextFields can share the same
* Blinker instance, because only one object can ever own the keyboard focus.
* @return the current Blinker instance
*/
public static void lazyLoad()
{
if (instance == null || !instance.isAlive())
{
instance = new Blinker(750);
instance.start();
}
}
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
try
{
synchronized (this)
{
if (!interrupted)
{
setState(!isOn);
} else
{
interrupted = false;
}
this.wait(delay);
}
} catch (InterruptedException e)
{
// e.printStackTrace();
break;
}
}
yield();
}
public synchronized void setState(boolean state)
{
if (state == isOn) return;
else isOn = state;
notifyListeners(); // Notify listeners of the state change.
}
public void notifyListeners()
{
for (int i=0; i < listeners.size(); i++)
{
BlinkListener b = (BlinkListener)listeners.get(i);
b.onBlink(this);
}
}
public void addBlinkListener(BlinkListener b)
{
listeners.add(b);
}
public void removeBlinkListener(BlinkListener b)
{
listeners.remove(b);
}
public synchronized void reset()
{
setState(true);
interrupted = true;
this.notifyAll();
}
interface BlinkListener
{
public void onBlink(Blinker b);
}
}