1 12 package org.eclipse.jface.databinding.viewers; 13 14 import java.util.Collections ; 15 import java.util.HashSet ; 16 import java.util.Set ; 17 18 import org.eclipse.core.databinding.observable.Diffs; 19 import org.eclipse.core.databinding.observable.IStaleListener; 20 import org.eclipse.core.databinding.observable.StaleEvent; 21 import org.eclipse.core.databinding.observable.set.IObservableSet; 22 import org.eclipse.core.databinding.observable.set.ISetChangeListener; 23 import org.eclipse.core.databinding.observable.set.ObservableSet; 24 import org.eclipse.core.databinding.observable.set.SetChangeEvent; 25 import org.eclipse.jface.databinding.swt.SWTObservables; 26 import org.eclipse.jface.viewers.AbstractListViewer; 27 import org.eclipse.jface.viewers.IStructuredContentProvider; 28 import org.eclipse.jface.viewers.TableViewer; 29 import org.eclipse.jface.viewers.Viewer; 30 import org.eclipse.swt.widgets.Display; 31 32 36 public final class ObservableSetContentProvider implements 37 IStructuredContentProvider { 38 39 private class KnownElementsSet extends ObservableSet { 40 41 KnownElementsSet(Set wrappedSet) { 42 super(SWTObservables.getRealm(Display.getDefault()), wrappedSet, Object .class); 43 } 44 45 void doFireDiff(Set added, Set removed) { 46 fireSetChange(Diffs.createSetDiff(added, removed)); 47 } 48 49 void doFireStale(boolean isStale) { 50 if (isStale) { 51 fireStale(); 52 } else { 53 fireChange(); 54 } 55 } 56 } 57 58 private IObservableSet readableSet; 59 60 private Viewer viewer; 61 62 67 private KnownElementsSet knownElements; 68 69 private ISetChangeListener listener = new ISetChangeListener() { 70 71 public void handleSetChange(SetChangeEvent event) { 72 boolean wasStale = knownElements.isStale(); 73 if (isDisposed()) { 74 return; 75 } 76 doDiff(event.diff.getAdditions(), event.diff.getRemovals(), true); 77 if (!wasStale && event.getObservableSet().isStale()) { 78 knownElements.doFireStale(true); 79 } 80 } 81 }; 82 83 private IStaleListener staleListener = new IStaleListener() { 84 public void handleStale(StaleEvent event) { 85 knownElements.doFireStale(event.getObservable().isStale()); 86 } 87 }; 88 89 92 public ObservableSetContentProvider() { 93 readableSet = new ObservableSet(SWTObservables.getRealm(Display.getDefault()), 94 Collections.EMPTY_SET, Object .class) { 95 }; 96 knownElements = new KnownElementsSet(readableSet); 97 } 98 99 public void dispose() { 100 setInput(null); 101 } 102 103 private void doDiff(Set added, Set removed, boolean updateViewer) { 104 knownElements.doFireDiff(added, Collections.EMPTY_SET); 105 106 if (updateViewer) { 107 Object [] toAdd = added.toArray(); 108 if (viewer instanceof TableViewer) { 109 TableViewer tv = (TableViewer) viewer; 110 tv.add(toAdd); 111 } else if (viewer instanceof AbstractListViewer) { 112 AbstractListViewer lv = (AbstractListViewer) viewer; 113 lv.add(toAdd); 114 } 115 Object [] toRemove = removed.toArray(); 116 if (viewer instanceof TableViewer) { 117 TableViewer tv = (TableViewer) viewer; 118 tv.remove(toRemove); 119 } else if (viewer instanceof AbstractListViewer) { 120 AbstractListViewer lv = (AbstractListViewer) viewer; 121 lv.remove(toRemove); 122 } 123 } 124 knownElements.doFireDiff(Collections.EMPTY_SET, removed); 125 } 126 127 public Object [] getElements(Object inputElement) { 128 return readableSet.toArray(); 129 } 130 131 140 public IObservableSet getKnownElements() { 141 return knownElements; 142 } 143 144 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 145 this.viewer = viewer; 146 147 if (!(viewer instanceof TableViewer || viewer instanceof AbstractListViewer)) { 148 Class abstractTableViewerClass = null; 150 try { 151 abstractTableViewerClass = Class.forName("org.eclipse.jface.viewers.AbstractTableViewer"); } catch(Exception ex) { 153 } 155 if (abstractTableViewerClass == null || !abstractTableViewerClass.isInstance(viewer)) { 156 throw new IllegalArgumentException ( 157 "This content provider only works with (Abstract)TableViewer or AbstractListViewer"); } 159 } 160 161 if (newInput != null && !(newInput instanceof IObservableSet)) { 162 throw new IllegalArgumentException ( 163 "This content provider only works with input of type IReadableSet"); } 165 166 setInput((IObservableSet) newInput); 167 } 168 169 private boolean isDisposed() { 170 return viewer.getControl() == null || viewer.getControl().isDisposed(); 171 } 172 173 private void setInput(IObservableSet newSet) { 174 boolean updateViewer = true; 175 if (newSet == null) { 176 newSet = new ObservableSet(SWTObservables.getRealm(Display.getDefault()), Collections.EMPTY_SET, Object .class) { 177 }; 178 updateViewer = false; 180 } 181 182 boolean wasStale = false; 183 if (readableSet != null) { 184 wasStale = readableSet.isStale(); 185 readableSet.removeSetChangeListener(listener); 186 readableSet.removeStaleListener(staleListener); 187 } 188 189 HashSet additions = new HashSet (); 190 HashSet removals = new HashSet (); 191 192 additions.addAll(newSet); 193 additions.removeAll(readableSet); 194 195 removals.addAll(readableSet); 196 removals.removeAll(newSet); 197 198 readableSet = newSet; 199 200 doDiff(additions, removals, updateViewer); 201 202 if (readableSet != null) { 203 readableSet.addSetChangeListener(listener); 204 readableSet.addStaleListener(staleListener); 205 } 206 207 boolean isStale = (readableSet != null && readableSet.isStale()); 208 if (isStale != wasStale) { 209 knownElements.doFireStale(isStale); 210 } 211 } 212 213 } 214 | Popular Tags |