KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > internal > databinding > provisional > viewers > ObservableSetContentProvider


1 /*******************************************************************************
2  * Copyright (c) 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  ******************************************************************************/

11 package org.eclipse.jface.internal.databinding.provisional.viewers;
12
13 import java.util.Collections JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Set JavaDoc;
16
17 import org.eclipse.jface.internal.databinding.provisional.observable.Diffs;
18 import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
19 import org.eclipse.jface.internal.databinding.provisional.observable.IStaleListener;
20 import org.eclipse.jface.internal.databinding.provisional.observable.set.IObservableSet;
21 import org.eclipse.jface.internal.databinding.provisional.observable.set.ISetChangeListener;
22 import org.eclipse.jface.internal.databinding.provisional.observable.set.ObservableSet;
23 import org.eclipse.jface.internal.databinding.provisional.observable.set.SetDiff;
24 import org.eclipse.jface.viewers.AbstractListViewer;
25 import org.eclipse.jface.viewers.IStructuredContentProvider;
26 import org.eclipse.jface.viewers.TableViewer;
27 import org.eclipse.jface.viewers.Viewer;
28
29 /**
30  * @since 1.0
31  *
32  */

33 public final class ObservableSetContentProvider implements
34         IStructuredContentProvider {
35
36     private class KnownElementsSet extends ObservableSet {
37
38         KnownElementsSet(Set JavaDoc wrappedSet) {
39             super(wrappedSet, Object JavaDoc.class);
40         }
41
42         void doFireDiff(Set JavaDoc added, Set JavaDoc removed) {
43             fireSetChange(Diffs.createSetDiff(added, removed));
44         }
45
46         void doFireStale(boolean isStale) {
47             if (isStale) {
48                 fireStale();
49             } else {
50                 fireChange();
51             }
52         }
53     }
54
55     private IObservableSet readableSet = new ObservableSet(
56             Collections.EMPTY_SET, Object JavaDoc.class) {
57     };
58
59     private Viewer viewer;
60
61     /**
62      * This readableSet returns the same elements as the input readableSet.
63      * However, it only fires events AFTER the elements have been added or
64      * removed from the viewer.
65      */

66     private KnownElementsSet knownElements = new KnownElementsSet(readableSet);
67
68     private ISetChangeListener listener = new ISetChangeListener() {
69
70         public void handleSetChange(IObservableSet source, SetDiff diff) {
71             boolean wasStale = knownElements.isStale();
72             if (isDisposed()) {
73                 return;
74             }
75             doDiff(diff.getAdditions(), diff.getRemovals(), true);
76             if (!wasStale && source.isStale()) {
77                 knownElements.doFireStale(true);
78             }
79         }
80     };
81
82     private IStaleListener staleListener = new IStaleListener() {
83         public void handleStale(IObservable source) {
84             knownElements.doFireStale(source.isStale());
85         }
86     };
87
88     /**
89      *
90      */

91     public ObservableSetContentProvider() {
92     }
93
94     public void dispose() {
95         setInput(null);
96     }
97
98     private void doDiff(Set JavaDoc added, Set JavaDoc removed, boolean updateViewer) {
99         knownElements.doFireDiff(added, Collections.EMPTY_SET);
100
101         if (updateViewer) {
102             Object JavaDoc[] toAdd = added.toArray();
103             if (viewer instanceof TableViewer) {
104                 TableViewer tv = (TableViewer) viewer;
105                 tv.add(toAdd);
106             } else if (viewer instanceof AbstractListViewer) {
107                 AbstractListViewer lv = (AbstractListViewer) viewer;
108                 lv.add(toAdd);
109             }
110             Object JavaDoc[] toRemove = removed.toArray();
111             if (viewer instanceof TableViewer) {
112                 TableViewer tv = (TableViewer) viewer;
113                 tv.remove(toRemove);
114             } else if (viewer instanceof AbstractListViewer) {
115                 AbstractListViewer lv = (AbstractListViewer) viewer;
116                 lv.remove(toRemove);
117             }
118         }
119         knownElements.doFireDiff(Collections.EMPTY_SET, removed);
120     }
121
122     public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
123         return readableSet.toArray();
124     }
125
126     /**
127      * Returns the readableSet of elements known to this content provider. Items
128      * are added to this readableSet before being added to the viewer, and they
129      * are removed after being removed from the viewer. The readableSet is
130      * always updated after the viewer. This is intended for use by label
131      * providers, as it will always return the items that need labels.
132      *
133      * @return readableSet of items that will need labels
134      */

135     public IObservableSet getKnownElements() {
136         return knownElements;
137     }
138
139     public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {
140         this.viewer = viewer;
141
142         if (!(viewer instanceof TableViewer || viewer instanceof AbstractListViewer)) {
143             throw new IllegalArgumentException JavaDoc(
144                     "This content provider only works with TableViewer or AbstractListViewer"); //$NON-NLS-1$
145
}
146
147         if (newInput != null && !(newInput instanceof IObservableSet)) {
148             throw new IllegalArgumentException JavaDoc(
149                     "This content provider only works with input of type IReadableSet"); //$NON-NLS-1$
150
}
151
152         setInput((IObservableSet) newInput);
153     }
154
155     private boolean isDisposed() {
156         return viewer.getControl() == null || viewer.getControl().isDisposed();
157     }
158
159     private void setInput(IObservableSet newSet) {
160         boolean updateViewer = true;
161         if (newSet == null) {
162             newSet = new ObservableSet(Collections.EMPTY_SET, Object JavaDoc.class) {
163             };
164             // don't update the viewer - its input is null
165
updateViewer = false;
166         }
167
168         boolean wasStale = false;
169         if (readableSet != null) {
170             wasStale = readableSet.isStale();
171             readableSet.removeSetChangeListener(listener);
172             readableSet.removeStaleListener(staleListener);
173         }
174
175         HashSet JavaDoc additions = new HashSet JavaDoc();
176         HashSet JavaDoc removals = new HashSet JavaDoc();
177
178         additions.addAll(newSet);
179         additions.removeAll(readableSet);
180
181         removals.addAll(readableSet);
182         removals.removeAll(newSet);
183
184         readableSet = newSet;
185
186         doDiff(additions, removals, updateViewer);
187
188         if (readableSet != null) {
189             readableSet.addSetChangeListener(listener);
190             readableSet.addStaleListener(staleListener);
191         }
192
193         boolean isStale = (readableSet != null && readableSet.isStale());
194         if (isStale != wasStale) {
195             knownElements.doFireStale(isStale);
196         }
197     }
198
199 }
200
Popular Tags