diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableItemModelAdapter.java')
-rw-r--r-- | jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableItemModelAdapter.java | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableItemModelAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableItemModelAdapter.java new file mode 100644 index 0000000000..aa17710792 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableItemModelAdapter.java @@ -0,0 +1,209 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.ui.internal.swt; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper; +import org.eclipse.jpt.utility.internal.StringTools; +import org.eclipse.jpt.utility.model.event.PropertyChangeEvent; +import org.eclipse.jpt.utility.model.listener.PropertyChangeListener; +import org.eclipse.jpt.utility.model.value.PropertyValueModel; +import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; + +/** + * This adapter can be used to keep a table item in synch with the properties of + * a model. + */ +@SuppressWarnings("nls") +public class TableItemModelAdapter { + + /** The table item we synchronize with the model. */ + protected final TableItem tableItem; + + /** + * A listener that allows us to stop listening to stuff when the button + * is disposed. + */ + protected final DisposeListener tableItemDisposeListener; + + /** + * Client-supplied adapter that provides with the various column settings and + * converts the objects in the LVM into an array of cell models. + */ + private ColumnAdapter<Object> columnAdapter; + + /** + * The value models used to listen to each property that are display by the + * table item. + */ + private WritablePropertyValueModel<?>[] valueHolders; + + /** + * The list of <code>PropertyChangeListener</code>s used to be notified when + * the properties of the model being display into a row change. + */ + private PropertyChangeListener[] propertyChangeListeners; + + /** + * The label used to format the objects into a string representation. + */ + private ITableLabelProvider labelProvider; + + // ********** static methods ********** + + /** + * Adapt the specified boolean to the specified button. + * If the boolean is null, the button's value will be "unselected". + */ + public static TableItemModelAdapter adapt(TableItem tableItem, ColumnAdapter<?> columnAdapter, ITableLabelProvider labelProvider) { + return new TableItemModelAdapter(tableItem, columnAdapter, labelProvider); + } + + + // ********** constructors ********** + + /** + * Constructor - the boolean holder and button are required. + */ + @SuppressWarnings("unchecked") + protected TableItemModelAdapter(TableItem tableItem, ColumnAdapter<?> columnAdapter, ITableLabelProvider labelProvider) { + super(); + if (tableItem == null || columnAdapter == null || labelProvider == null) { + throw new NullPointerException(); + } + this.tableItem = tableItem; + this.labelProvider = labelProvider; + this.columnAdapter = (ColumnAdapter<Object>) columnAdapter; + + this.tableItemDisposeListener = this.buildTableItemDisposeListener(); + this.tableItem.addDisposeListener(this.tableItemDisposeListener); + + this.valueHolders = this.columnAdapter.cellModels(tableItem.getData()); + this.propertyChangeListeners = this.buildPropertyChangeListeners(); + + for (int index = this.columnAdapter.columnCount(); --index >= 0; ) { + tableItemChanged(index, tableItem.getData(), false); + valueHolders[index].addPropertyChangeListener(PropertyValueModel.VALUE, propertyChangeListeners[index]); + } + } + + + // ********** initialization ********** + + private PropertyChangeListener[] buildPropertyChangeListeners() { + PropertyChangeListener[] listeners = new PropertyChangeListener[columnAdapter.columnCount()]; + for (int index = listeners.length; --index >= 0; ) { + listeners[index] = buildPropertyChangeListener(index); + } + return listeners; + } + + + protected PropertyChangeListener buildPropertyChangeListener(int index) { + return new SWTPropertyChangeListenerWrapper( + this.buildPropertyChangeListener_(index) + ); + } + + protected PropertyChangeListener buildPropertyChangeListener_(int index) { + return new TableItemPropertyChangeListener(index); + } + + protected DisposeListener buildTableItemDisposeListener() { + return new DisposeListener() { + public void widgetDisposed(DisposeEvent event) { + TableItemModelAdapter.this.tableItemDisposed(event); + } + @Override + public String toString() { + return "TableItem dispose listener"; + } + }; + } + + + // ********** behavior ********** + + protected void tableItemChanged(int index, Object subject, boolean revalidate) { + + if (!this.tableItem.isDisposed()) { + this.updateTableItemText(index, subject); + this.updateTableItemImage(index, subject); + + if (revalidate) { + this.layoutTable(); + } + } + } + + private void updateTableItemText(int index, Object subject) { + String text = this.labelProvider.getColumnText(subject, index); + if (text == null) { + text = ""; + } + this.tableItem.setText(index, text); + } + + private void updateTableItemImage(int index, Object subject) { + Image image = this.labelProvider.getColumnImage(subject, index); + this.tableItem.setImage(index, image); + } + + private void layoutTable() { + // Refresh the table in order to show the scrollbar if required + Composite container = this.tableItem.getParent().getParent(); + container.computeSize(SWT.DEFAULT, SWT.DEFAULT); + container.layout(); + } + + // ********** dispose ********** + + protected void tableItemDisposed(DisposeEvent event) { + // the button is not yet "disposed" when we receive this event + // so we can still remove our listeners + this.tableItem.removeDisposeListener(this.tableItemDisposeListener); + + for (int index = valueHolders.length; --index >= 0; ) { + valueHolders[index].removePropertyChangeListener(PropertyValueModel.VALUE, propertyChangeListeners[index]); + } + } + + + // ********** standard methods ********** + + @Override + public String toString() { + return StringTools.buildToStringFor(this); + } + + private class TableItemPropertyChangeListener implements PropertyChangeListener { + + private final int index; + + TableItemPropertyChangeListener(int index) { + super(); + this.index = index; + } + + public void propertyChanged(PropertyChangeEvent event) { + if (!tableItem.isDisposed()) { + Table table = tableItem.getParent(); + tableItemChanged(index, tableItem.getData(), table.getColumnCount() == 0); + } + } + } +}
\ No newline at end of file |