Merge branch 'subtree'
[fanfix.git] / src / be / nikiroo / utils / ui / ListenerPanel.java
1 package be.nikiroo.utils.ui;
2
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.util.LinkedList;
6 import java.util.Queue;
7
8 import javax.swing.JPanel;
9
10 /**
11 * A {@link JPanel} with the default {@link ActionListener} add/remove/fire
12 * methods.
13 * <p>
14 * Note that it will queue all events until at least one listener comes (or
15 * comes back!); this first (or at least currently unique) listener will drain
16 * the queue.
17 *
18 * @author niki
19 */
20 public class ListenerPanel extends JPanel {
21 private static final long serialVersionUID = 1L;
22
23 /** Waiting queue until at least one listener is here to get the events. */
24 private final Queue<ActionEvent> waitingQueue;
25
26 /**
27 * Create a new {@link ListenerPanel}.
28 */
29 public ListenerPanel() {
30 waitingQueue = new LinkedList<ActionEvent>();
31 }
32
33 /**
34 * Check that this {@link ListenerPanel} currently has
35 * {@link ActionListener}s that listen on it.
36 *
37 * @return TRUE if it has
38 */
39 public synchronized boolean hasListeners() {
40 return listenerList.getListenerList().length > 1;
41 }
42
43 /**
44 * Check how many events are currently waiting for an
45 * {@link ActionListener}.
46 *
47 * @return the number of waiting events (can be 0)
48 */
49 public synchronized int getWaitingEventCount() {
50 return waitingQueue.size();
51 }
52
53 /**
54 * Adds the specified action listener to receive action events from this
55 * {@link ListenerPanel}.
56 *
57 * @param listener
58 * the action listener to be added
59 */
60 public synchronized void addActionListener(ActionListener listener) {
61 if (!hasListeners()) {
62 while (!waitingQueue.isEmpty()) {
63 listener.actionPerformed(waitingQueue.remove());
64 }
65 }
66
67 listenerList.add(ActionListener.class, listener);
68 }
69
70 /**
71 * Removes the specified action listener so that it no longer receives
72 * action events from this {@link ListenerPanel}.
73 *
74 * @param listener
75 * the action listener to be removed
76 */
77 public synchronized void removeActionListener(ActionListener listener) {
78 listenerList.remove(ActionListener.class, listener);
79 }
80
81 /**
82 * Notify the listeners of an action.
83 *
84 * @param listenerCommand
85 * A string that may specify a command (possibly one of several)
86 * associated with the event
87 */
88 protected synchronized void fireActionPerformed(String listenerCommand) {
89 ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
90 listenerCommand);
91
92 ActionListener[] listeners = getListeners(ActionListener.class);
93 if (listeners.length > 0) {
94 for (ActionListener action : listeners) {
95 action.actionPerformed(e);
96 }
97 } else {
98 waitingQueue.add(e);
99 }
100 }
101 }