1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
39
40
41
42 private LinkedList insertCache = new LinkedList();
43 private SwingListListener listener;
44 private boolean insertPending = false;
45 private volatile int maxInsertsPerRun = 100;
46
47
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
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 }