Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » JFace » Getting TableViewerColumns from TableViewer reference?
Getting TableViewerColumns from TableViewer reference? [message #541721] Tue, 22 June 2010 06:23 Go to next message
SlowStrider Mising name is currently offline SlowStrider Mising name
Messages: 110
Registered: July 2009
Senior Member
Is it possible to get references to all TableViewerColumns in one TableViewer given only the reference to the TableViewer?

(I am writing some generic databinding code so that we can bind to a design of the TableViewer and TableViewerColumns made with SWT designer and this would save us some work in exposing the columns and passing references to the data binder)
Re: Getting TableViewerColumns from TableViewer reference? [message #541724 is a reply to message #541721] Tue, 22 June 2010 06:32 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5014
Registered: July 2009
Senior Member
Not through public API but the relation is stored in the in the
Table#getData(Policy.JFACE + ".columnViewer") key.

Tom

Am 22.06.10 12:23, schrieb SlowStrider:
> Is it possible to get references to all TableViewerColumns in one
> TableViewer given only the reference to the TableViewer?
>
> (I am writing some generic databinding code so that we can bind to a
> design of the TableViewer and TableViewerColumns made with SWT designer
> and this would save us some work in exposing the columns and passing
> references to the data binder)
Re: Getting TableViewerColumns from TableViewer reference? [message #541725 is a reply to message #541724] Tue, 22 June 2010 06:33 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5014
Registered: July 2009
Senior Member
Ups TableColumn#getData()


Am 22.06.10 12:32, schrieb Tom Schindl:
> Not through public API but the relation is stored in the in the
> Table#getData(Policy.JFACE + ".columnViewer") key.
>
> Tom
>
> Am 22.06.10 12:23, schrieb SlowStrider:
>> Is it possible to get references to all TableViewerColumns in one
>> TableViewer given only the reference to the TableViewer?
>>
>> (I am writing some generic databinding code so that we can bind to a
>> design of the TableViewer and TableViewerColumns made with SWT designer
>> and this would save us some work in exposing the columns and passing
>> references to the data binder)
>
Re: Getting TableViewerColumns from TableViewer reference? [message #541947 is a reply to message #541725] Wed, 23 June 2010 06:38 Go to previous messageGo to next message
SlowStrider Mising name is currently offline SlowStrider Mising name
Messages: 110
Registered: July 2009
Senior Member
Thank you! Works like a charm:

	/**
	 * Utility method for getting the {@link TableViewerColumn}s in a
	 * {@link TableViewer}.
	 * 
	 * <p>
	 * WARNING: this method uses internal jface implementation and may not work
	 * for future versions.
	 */
	public static TableViewerColumn[] getTableViewerColumns(
			TableViewer tableViewer) {
		TableColumn[] columns = tableViewer.getTable().getColumns();
		TableViewerColumn[] viewerColumns = new TableViewerColumn[columns.length];
		for (int i = 0; i < columns.length; i++) {
			TableColumn tableColumn = columns[i];
			viewerColumns[i] = (TableViewerColumn) tableColumn
					.getData(Policy.JFACE + ".columnViewer");
		}
		return viewerColumns;
	}

[Updated on: Wed, 23 June 2010 06:56]

Report message to a moderator

Re: Getting TableViewerColumns from TableViewer reference? [message #541949 is a reply to message #541947] Wed, 23 June 2010 06:43 Go to previous messageGo to next message
SlowStrider Mising name is currently offline SlowStrider Mising name
Messages: 110
Registered: July 2009
Senior Member
For people who are interested, here I give the TableViewerBinder utility I came up with. I factored it out of Snippet032TableViewerColumnEditing and I also give my refactored version of this snippet here.
Note that I also fixed this bug in the snippet.
I also used ViewerSupport to simplify the code that binds the label provider.

package org.eclipse.jface.examples.databinding.snippets;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.CellEditorProperties;
import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport;
import org.eclipse.jface.databinding.viewers.ViewerSupport;
import org.eclipse.jface.util.Policy;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.TableColumn;

/**
 * Provides basic support for binding a {@link TableViewer} to a collection of
 * model objects.
 * 
 * @author Henno Vermeulen
 */
public final class TableViewerBinder {

	private DataBindingContext bindingContext;

	public TableViewerBinder() {
		this(new DataBindingContext());
	}

	public TableViewerBinder(DataBindingContext bindingContext) {
		this.bindingContext = bindingContext;
	}

	public DataBindingContext getBindingContext() {
		return bindingContext;
	}

	public void bind(TableViewer peopleViewer, IObservableList input,
			String[] propertyNames) {
		bindInputAndLabels(peopleViewer, input, propertyNames);
		bindCellEditors(peopleViewer, propertyNames);
	}

	private void bindInputAndLabels(TableViewer peopleViewer,
			IObservableList input, String[] propertyNames) {
		// Note: for efficiency we can consider reusing BeanProperties
		// .values inside bindCellEditors
		ViewerSupport.bind(peopleViewer, input, BeanProperties
				.values(propertyNames));
	}

	private void bindCellEditors(TableViewer tableViewer, String... properties) {
		ColumnBinder binder = new ColumnBinder(bindingContext, tableViewer);
		TableViewerColumn[] columns = getTableViewerColumns(tableViewer);
		for (int i = 0; i < columns.length; i++) {
			binder.bind(columns[i], properties[i]);
		}
	}

	static class ColumnBinder {
		private DataBindingContext bindingContext;
		private TableViewer tableViewer;
		private IValueProperty cellEditorControlText;
		private TextCellEditor cellEditor;

		public ColumnBinder(DataBindingContext bindingContext,
				TableViewer tableViewer) {
			this.bindingContext = bindingContext;
			this.tableViewer = tableViewer;
			cellEditorControlText = CellEditorProperties.control().value(
					WidgetProperties.text(SWT.Modify));
			cellEditor = new TextCellEditor(tableViewer.getTable());
		}

		public void bind(TableViewerColumn columnName, String propertyName) {
			columnName.setEditingSupport(ObservableValueEditingSupport.create(
					tableViewer, bindingContext, cellEditor,
					cellEditorControlText, BeanProperties.value(propertyName)));
		}

	}

	/**
	 * Utility method for getting the {@link TableViewerColumn}s in a
	 * {@link TableViewer}.
	 * 
	 * <p>
	 * WARNING: this method uses internal jface implementation and may not work
	 * for future versions.
	 */
	public static TableViewerColumn[] getTableViewerColumns(
			TableViewer tableViewer) {
		TableColumn[] columns = tableViewer.getTable().getColumns();
		TableViewerColumn[] viewerColumns = new TableViewerColumn[columns.length];
		for (int i = 0; i < columns.length; i++) {
			TableColumn tableColumn = columns[i];
			viewerColumns[i] = (TableViewerColumn) tableColumn
					.getData(Policy.JFACE + ".columnViewer");
		}
		return viewerColumns;
	}

}


package org.eclipse.jface.examples.databinding.snippets;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;

/**
 * Demonstrates binding a TableViewer with multiple columns to a collection.
 * 
 * <p>
 * Based on Snippet032TableViewerColumnEditing. The logic for binding the
 * {@link TableViewer} to the model has been factored into the
 * {@link TableViewerBinder} class.
 */
public class Snippet032TableViewerColumnEditingRefactored {
	public static void main(String[] args) {
		final Display display = new Display();
		Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
			public void run() {
				ViewModel viewModel = new ViewModel();
				Shell shell = new View(viewModel).createShell();

				// The SWT event loop
				while (!shell.isDisposed()) {
					if (!display.readAndDispatch()) {
						display.sleep();
					}
				}
			}
		});
	}

	// Minimal JavaBeans support
	public static abstract class AbstractModelObject {
		private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
				this);

		public void addPropertyChangeListener(PropertyChangeListener listener) {
			propertyChangeSupport.addPropertyChangeListener(listener);
		}

		public void addPropertyChangeListener(String propertyName,
				PropertyChangeListener listener) {
			propertyChangeSupport.addPropertyChangeListener(propertyName,
					listener);
		}

		public void removePropertyChangeListener(PropertyChangeListener listener) {
			propertyChangeSupport.removePropertyChangeListener(listener);
		}

		public void removePropertyChangeListener(String propertyName,
				PropertyChangeListener listener) {
			propertyChangeSupport.removePropertyChangeListener(propertyName,
					listener);
		}

		protected void firePropertyChange(String propertyName, Object oldValue,
				Object newValue) {
			propertyChangeSupport.firePropertyChange(propertyName, oldValue,
					newValue);
		}
	}

	// The data model class. This is normally a persistent class of some sort.
	static class Person extends AbstractModelObject {

		public static final String[] propertyNames = new String[] { "name",
				"firstName" };
		// A property...
		String name;
		String firstName;

		public Person(String firstName, String name) {
			this.name = name;
			this.firstName = firstName;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			firePropertyChange("name", this.name, this.name = name);
		}

		public String getFirstName() {
			return firstName;
		}

		public void setFirstName(String firstName) {
			firePropertyChange("firstName", this.firstName,
					this.firstName = firstName);
		}
	}

	// The View's model--the root of our Model graph for this particular GUI.
	//
	// Typically each View class has a corresponding ViewModel class.
	// The ViewModel is responsible for getting the objects to edit from the
	// data access tier. Since this snippet doesn't have any persistent objects
	// ro retrieve, this ViewModel just instantiates a model object to edit.
	static class ViewModel {
		// The model to bind
		private List people = new LinkedList();
		{
			people.add(new Person("Dave", "Orme"));
			people.add(new Person("Gili", "Mendel"));
			people.add(new Person("Joe", "Winchester"));
			people.add(new Person("Boris", "Bokowski"));
			people.add(new Person("Brad", "Reynolds"));
			people.add(new Person("Matthew", "Hall"));
		}

		public List getPeople() {
			return people;
		}
	}

	// The GUI view
	static class View {
		private ViewModel viewModel;
		private Table committers;
		private Label selectedCommitterName;
		private Label selectedCommitterFirstName;

		public View(ViewModel viewModel) {
			this.viewModel = viewModel;
		}

		public Shell createShell() {
			// Build a UI
			Display display = Display.getDefault();
			Shell shell = new Shell(display);
			shell.setLayout(new GridLayout(2, true));

			TableViewer peopleViewer = createTableViewer(shell);
			createDetailView(shell);

			DataBindingContext bindingContext = new DataBindingContext();
			WritableList input = new WritableList(viewModel.getPeople(),
					Person.class);
			new TableViewerBinder(bindingContext).bind(peopleViewer, input,
					Person.propertyNames);
			bindDetails(bindingContext, peopleViewer);

			// Open and return the Shell
			shell.setSize(250, 300);
			shell.open();
			return shell;
		}

		private TableViewer createTableViewer(Composite parent) {
			committers = new Table(parent, SWT.BORDER | SWT.FULL_SELECTION);
			committers.setLinesVisible(true);
			committers.setHeaderVisible(true);
			GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
			layoutData.horizontalSpan = 2;
			committers.setLayoutData(layoutData);

			// Since we're using a JFace Viewer, we do first wrap our Table...
			TableViewer peopleViewer = new TableViewer(committers);

			TableViewerColumn columnName = new TableViewerColumn(peopleViewer,
					SWT.NONE);
			columnName.getColumn().setText("Name");
			columnName.getColumn().setWidth(100);

			TableViewerColumn columnFirstName = new TableViewerColumn(
					peopleViewer, SWT.NONE);
			columnFirstName.getColumn().setText("FirstName");
			columnFirstName.getColumn().setWidth(100);
			return peopleViewer;
		}

		private void createDetailView(Composite parent) {
			GridData fieldLayoutData = new GridData(SWT.FILL, SWT.BEGINNING,
					true, false);
			selectedCommitterName = new Label(parent, SWT.NONE);
			selectedCommitterName.setLayoutData(fieldLayoutData);

			selectedCommitterFirstName = new Label(parent, SWT.NONE);
			selectedCommitterFirstName.setLayoutData(fieldLayoutData);
		}

		private void bindDetails(DataBindingContext bindingContext,
				TableViewer peopleViewer) {
			// bind selectedCommitter labels to the name and forname of the
			// current selection
			IObservableValue selection = ViewersObservables
					.observeSingleSelection(peopleViewer);
			bindingContext.bindValue(SWTObservables
					.observeText(selectedCommitterName), BeansObservables
					.observeDetailValue(selection, "name", String.class));
			bindingContext.bindValue(SWTObservables
					.observeText(selectedCommitterFirstName), BeansObservables
					.observeDetailValue(selection, "firstName", String.class));
		}
	}
}

[Updated on: Wed, 23 June 2010 06:56]

Report message to a moderator

Re: Getting TableViewerColumns from TableViewer reference? [message #541950 is a reply to message #541947] Wed, 23 June 2010 06:45 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5014
Registered: July 2009
Senior Member
Please note that this is an implementation detail :-)

I see no reason we'd change this in future but don't blame us if your
code is not working anymore one day.

Tom

Am 23.06.10 12:38, schrieb SlowStrider:
> Thank you! Works like a charm:
>
>
> public static TableViewerColumn[] getTableViewerColumns(
> TableViewer tableViewer) {
> TableColumn[] columns = tableViewer.getTable().getColumns();
> TableViewerColumn[] viewerColumns = new
> TableViewerColumn[columns.length];
> for (int i = 0; i < columns.length; i++) {
> TableColumn tableColumn = columns[i];
> viewerColumns[i] = (TableViewerColumn) tableColumn
> .getData(Policy.JFACE + ".columnViewer");
> }
> return viewerColumns;
> }
>
Re: Getting TableViewerColumns from TableViewer reference? [message #541951 is a reply to message #541950] Wed, 23 June 2010 06:55 Go to previous message
SlowStrider Mising name is currently offline SlowStrider Mising name
Messages: 110
Registered: July 2009
Senior Member
Allright, I will keep this in mind! I will comment this and make a simple JUnit test for it and when it breaks in the future it shouldn't be hard to change the binder to accept an extra array of TableViewerColumns.
Previous Topic:TreeViewer with Columns
Next Topic:Exporting RCP product
Goto Forum:
  


Current Time: Mon Apr 21 03:09:54 EDT 2014

Powered by FUDForum. Page generated in 0.09428 seconds