1 11 package org.eclipse.jface.internal.databinding.provisional.swt; 12 13 import org.eclipse.core.databinding.observable.ChangeEvent; 14 import org.eclipse.core.databinding.observable.IChangeListener; 15 import org.eclipse.core.databinding.observable.IObservable; 16 import org.eclipse.core.databinding.observable.ObservableTracker; 17 import org.eclipse.core.runtime.Assert; 18 import org.eclipse.swt.SWT; 19 import org.eclipse.swt.events.DisposeEvent; 20 import org.eclipse.swt.events.DisposeListener; 21 import org.eclipse.swt.widgets.Event; 22 import org.eclipse.swt.widgets.Listener; 23 import org.eclipse.swt.widgets.Table; 24 import org.eclipse.swt.widgets.TableItem; 25 26 31 public abstract class TableUpdater { 32 33 private class UpdateRunnable implements Runnable , IChangeListener, 34 DisposeListener { 35 private TableItem item; 36 37 private boolean dirty = false; 38 39 private IObservable[] dependencies = new IObservable[0]; 40 41 UpdateRunnable(TableItem item) { 42 this.item = item; 43 item.addDisposeListener(this); 44 } 45 46 public void run() { 50 if (theTable != null && !theTable.isDisposed() && item != null && !item.isDisposed()) { 51 if (theTable.isVisible()) { 52 int tableHeight = theTable.getClientArea().height; 53 int numVisibleItems = tableHeight / theTable.getItemHeight(); 54 int indexOfItem = theTable.indexOf(item); 55 int topIndex = theTable.getTopIndex(); 56 if (indexOfItem >= topIndex && indexOfItem <= topIndex+numVisibleItems) { 57 updateIfNecessary(); 58 return; 59 } 60 } 61 theTable.clear(theTable.indexOf(item)); 62 } 63 } 64 65 private void updateIfNecessary() { 66 if (dirty) { 67 dependencies = ObservableTracker.runAndMonitor(new Runnable () { 68 public void run() { 69 updateItem(item); 70 } 71 }, this, null); 72 dirty = false; 73 } 74 } 75 76 public void handleChange(ChangeEvent event) { 78 makeDirty(); 80 } 81 82 protected final void makeDirty() { 83 if (!dirty) { 84 dirty = true; 85 stopListening(); 86 SWTUtil.runOnce(theTable.getDisplay(), this); 87 } 88 } 89 90 private void stopListening() { 91 for (int i = 0; i < dependencies.length; i++) { 93 IObservable observable = dependencies[i]; 94 95 observable.removeChangeListener(this); 96 } 97 } 98 99 public void widgetDisposed(DisposeEvent e) { 101 stopListening(); 102 dependencies = null; 103 item = null; 104 } 105 } 106 107 private class PrivateInterface implements Listener, DisposeListener { 108 109 public void handleEvent(Event e) { 111 if (e.type == SWT.SetData) { 112 UpdateRunnable runnable = (UpdateRunnable) e.item.getData(); 113 if (runnable == null) { 114 runnable = new UpdateRunnable((TableItem) e.item); 115 e.item.setData(runnable); 116 runnable.makeDirty(); 117 } else { 118 runnable.updateIfNecessary(); 119 } 120 } 121 } 122 123 public void widgetDisposed(DisposeEvent e) { 125 TableUpdater.this.dispose(); 126 } 127 128 } 129 130 private PrivateInterface privateInterface = new PrivateInterface(); 131 132 private Table theTable; 133 134 140 public TableUpdater(Table toUpdate) { 141 Assert.isLegal((toUpdate.getStyle() & SWT.VIRTUAL) != 0, "TableUpdater requires virtual table"); theTable = toUpdate; 143 144 theTable.addDisposeListener(privateInterface); 145 theTable.addListener(SWT.SetData, privateInterface); 146 } 147 148 154 public void dispose() { 155 theTable.removeDisposeListener(privateInterface); 156 theTable.removeListener(SWT.SetData, privateInterface); 157 158 } 159 160 171 protected abstract void updateItem(TableItem item); 172 173 } 174 | Popular Tags |