package be.nikiroo.utils.ui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.JPanel;
/**
* A {@link JPanel} with the default {@link ActionListener} add/remove/fire
* methods.
*
* Note that it will queue all events until at least one listener comes (or
* comes back!); this first (or at least currently unique) listener will drain
* the queue.
*
* @author niki
*/
public class ListenerPanel extends JPanel {
private static final long serialVersionUID = 1L;
/** Waiting queue until at least one listener is here to get the events. */
private final Queue waitingQueue;
/**
* Create a new {@link ListenerPanel}.
*/
public ListenerPanel() {
waitingQueue = new LinkedList();
}
/**
* Check that this {@link ListenerPanel} currently has
* {@link ActionListener}s that listen on it.
*
* @return TRUE if it has
*/
public synchronized boolean hasListeners() {
return listenerList.getListenerList().length > 1;
}
/**
* Check how many events are currently waiting for an
* {@link ActionListener}.
*
* @return the number of waiting events (can be 0)
*/
public synchronized int getWaitingEventCount() {
return waitingQueue.size();
}
/**
* Adds the specified action listener to receive action events from this
* {@link ListenerPanel}.
*
* @param listener
* the action listener to be added
*/
public synchronized void addActionListener(ActionListener listener) {
if (!hasListeners()) {
while (!waitingQueue.isEmpty()) {
listener.actionPerformed(waitingQueue.remove());
}
}
listenerList.add(ActionListener.class, listener);
}
/**
* Removes the specified action listener so that it no longer receives
* action events from this {@link ListenerPanel}.
*
* @param listener
* the action listener to be removed
*/
public synchronized void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
/**
* Notify the listeners of an action.
*
* @param listenerCommand
* A string that may specify a command (possibly one of several)
* associated with the event
*/
protected synchronized void fireActionPerformed(String listenerCommand) {
ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
listenerCommand);
ActionListener[] listeners = getListeners(ActionListener.class);
if (listeners.length > 0) {
for (ActionListener action : listeners) {
action.actionPerformed(e);
}
} else {
waitingQueue.add(e);
}
}
}