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