1 11 package org.eclipse.jface.internal.databinding.provisional.viewers; 12 13 import java.util.Collections ; 14 import java.util.HashSet ; 15 import java.util.Set ; 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 33 public final class ObservableSetContentProvider implements 34 IStructuredContentProvider { 35 36 private class KnownElementsSet extends ObservableSet { 37 38 KnownElementsSet(Set wrappedSet) { 39 super(wrappedSet, Object .class); 40 } 41 42 void doFireDiff(Set added, Set 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 .class) { 57 }; 58 59 private Viewer viewer; 60 61 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 91 public ObservableSetContentProvider() { 92 } 93 94 public void dispose() { 95 setInput(null); 96 } 97 98 private void doDiff(Set added, Set removed, boolean updateViewer) { 99 knownElements.doFireDiff(added, Collections.EMPTY_SET); 100 101 if (updateViewer) { 102 Object [] 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 [] 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 [] getElements(Object inputElement) { 123 return readableSet.toArray(); 124 } 125 126 135 public IObservableSet getKnownElements() { 136 return knownElements; 137 } 138 139 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 140 this.viewer = viewer; 141 142 if (!(viewer instanceof TableViewer || viewer instanceof AbstractListViewer)) { 143 throw new IllegalArgumentException ( 144 "This content provider only works with TableViewer or AbstractListViewer"); } 146 147 if (newInput != null && !(newInput instanceof IObservableSet)) { 148 throw new IllegalArgumentException ( 149 "This content provider only works with input of type IReadableSet"); } 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 .class) { 163 }; 164 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 additions = new HashSet (); 176 HashSet removals = new HashSet (); 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 |