some update/refresh fixes
[fanfix.git] / src / be / nikiroo / fanfix_swing / gui / utils / ListenerPanel.java
index 7ed5f8618b7676b96ad6acf7d8ce473ef9cd7f76..98202b2da42108c44beee3119fb32a2b4bf1cec1 100644 (file)
@@ -2,6 +2,8 @@ package be.nikiroo.fanfix_swing.gui.utils;
 
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.util.LinkedList;
+import java.util.Queue;
 
 import javax.swing.JPanel;
 
@@ -10,12 +12,44 @@ import be.nikiroo.fanfix_swing.gui.SearchBar;
 /**
  * A {@link JPanel} with the default {@link ActionListener} add/remove/fire
  * methods.
+ * <p>
+ * Note that it will queue all events until at least one listener comes (or
+ * comes back!); this first (or at least curently unique) listener will drain
+ * the queue.
  * 
  * @author niki
  */
 public class ListenerPanel extends JPanel {
        private static final long serialVersionUID = 1L;
 
+       private final Queue<ActionEvent> waitingQueue;
+
+       /**
+        * Create a new {@link ListenerPanel}.
+        */
+       public ListenerPanel() {
+               waitingQueue = new LinkedList<ActionEvent>();
+       }
+
+       /**
+        * 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 SearchBar}.
@@ -23,6 +57,12 @@ public class ListenerPanel extends JPanel {
         * @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);
        }
 
@@ -42,13 +82,17 @@ public class ListenerPanel extends JPanel {
         * @param listenerCommand A string that may specify a command (possibly one of
         *                        several) associated with the event
         */
-       protected void fireActionPerformed(String listenerCommand) {
+       protected synchronized void fireActionPerformed(String listenerCommand) {
                ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, listenerCommand);
-               Object[] listeners = listenerList.getListenerList();
-               for (int i = listeners.length - 2; i >= 0; i -= 2) {
-                       if (listeners[i] == ActionListener.class) {
-                               ((ActionListener) listeners[i + 1]).actionPerformed(e);
+               if (hasListeners()) {
+                       Object[] listeners = listenerList.getListenerList();
+                       for (int i = listeners.length - 2; i >= 0; i -= 2) {
+                               if (listeners[i] == ActionListener.class) {
+                                       ((ActionListener) listeners[i + 1]).actionPerformed(e);
+                               }
                        }
+               } else {
+                       waitingQueue.add(e);
                }
        }
 }