View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.gui.util;
21  
22  import java.util.Iterator;
23  import java.util.LinkedList;
24  
25  import javax.swing.SwingUtilities;
26  
27  import org.xnap.event.ListEvent;
28  import org.xnap.event.ListListener;
29  import org.xnap.gui.event.SwingListListener;
30  
31  /***
32   * This class caches {@link ListEvent} objects and adds them in a
33   * Swing synchronized manner to a {@link SwingListListener}.
34   */
35  public class SwingSynchronizedCache implements ListListener
36  {
37  
38      //--- Constant(s) ---
39  
40      //--- Data field(s) ---
41  
42      private LinkedList insertCache = new LinkedList();
43      private SwingListListener listener;
44      private boolean insertPending = false;
45      private volatile int maxInsertsPerRun = 100;
46  
47      //--- Constructor(s) ---
48  
49      /***
50       * Constructs a cache.
51       *
52       * @param listener the event receiver
53       */
54      public SwingSynchronizedCache(SwingListListener listener)
55      {
56  		this.listener = listener;
57      }
58  
59      //--- Method(s) ---
60  
61      /***
62       * Adds <code>event</code> to cache.
63       */
64      public void itemAdded(ListEvent event)
65      {
66  		addToCache(event);
67      }
68  
69      /***
70       * Adds <code>event</code> to cache.
71       */
72      public void itemRemoved(ListEvent event)
73      {
74  		addToCache(event);
75      }
76  
77      /***
78       * Sets the maximum number of event objects that is handled per
79       * run.
80       */
81      public void setMaxInsertsPerRun(int newValue)
82      {
83  		maxInsertsPerRun = newValue;
84      }
85  
86      private void addToCache(ListEvent event) 
87      {
88  		synchronized (insertCache) {
89  			insertCache.addLast(event);
90  			if (insertPending) {
91  				return;
92  			}
93  			insertPending = true;
94  		}
95  		SwingUtilities.invokeLater(new InsertRunnable());
96      }
97  
98      private class InsertRunnable implements Runnable
99      {
100 		public void run() 
101 		{
102 			synchronized (insertCache) {
103 				int j = 0;
104 				for (Iterator i = insertCache.iterator();
105 					 i.hasNext() && j < maxInsertsPerRun; j++) {
106 					ListEvent e = (ListEvent)i.next();
107 					if (e.getID() == ListEvent.ITEM_ADDED) {
108 						listener.itemsAdded(new Object[] { e.getItem() });
109 					}
110 					else {
111 						listener.itemsRemoved(new Object[] { e.getItem() });
112 					}
113 
114 					i.remove();
115 				}
116 
117 				if (insertCache.size() > 0) {
118 					SwingUtilities.invokeLater(this);
119 				}    
120 				else {
121 					insertPending = false;
122 				}
123 			}
124 		}
125     }
126 
127 }