Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » JFace » Problem sorting table with TableEditor item(underlying TableItem is sorted, native checkbox is not)
Problem sorting table with TableEditor item [message #697655] Sun, 17 July 2011 12:19 Go to next message
Andreas Fagschlunger is currently offline Andreas Fagschlunger
Messages: 12
Registered: June 2011
Junior Member
Hy all!

I have a program that displays Books with Writers and status Read/Unread. The read/unread status is displayed by native checkbox (Table Editor). I realy need the native look & feel here!

No I tried to get the sorting to work. But as my sample application shows, the checkboxes are not sorted.

Please note, only the first column (book title) is sortable. The LabelProvider for the Read/Unread column returns a text (true / false). When sorting is applied, the TableItem gets sorted - the order of the read/unread changes - but the Checkboxes doesn't do so. So there is a checked box with the text "false" which doesn't make sense.

Does anyone knows how to fix this issue?

Just copy an run the main-method:
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.IViewerUpdater;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

public class LibraryTest implements Runnable {

	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);
		}
	}

	class Writer extends AbstractModelObject {
		private String firstName = null;
		private String lastName = null;

		public Writer(String firstName, String lastName) {
			this.firstName = firstName;
			this.lastName = lastName;
		}

		public String getFirstName() {
			return firstName;
		}

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

		public String getLastName() {
			return lastName;
		}

		public void setLastName(String lastName) {
			firePropertyChange("lastName", this.lastName,
					this.lastName = lastName);
		}
	}

	class Book extends AbstractModelObject {
		private String title = null;
		private Boolean read = null;
		private List<Writer> writers = null;

		public Book() {
			writers = new ArrayList<Writer>();
		}

		public Book(String title) {
			this();
			this.title = title;
		}

		public String getTitle() {
			return title;
		}

		public void setTitle(String title) {
			firePropertyChange("title", this.title, this.title = title);
		}

		public Boolean getRead() {
			return read;
		}

		public void setRead(Boolean read) {
			this.read = read;
		}

		public List<Writer> getWriters() {
			return writers;
		}

		public void setWriters(List<Writer> writers) {
			firePropertyChange("writers", this.writers, this.writers = writers);
		}

	}

	class BookViewerComparator extends ViewerComparator {

		private int direction = SWT.UP;

		@Override
		public int compare(Viewer viewer, Object e1, Object e2) {
			Book book1 = (Book) e1;
			Book book2 = (Book) e2;
			int result = book1.getTitle().compareToIgnoreCase(book2.getTitle());
			if (direction == SWT.UP) {
				result = -result;
			}
			return result;
		}

		public int change() {
			if (direction == SWT.UP) {
				direction = SWT.DOWN;
			} else {
				direction = SWT.UP;
			}
			return direction;
		}
	}

	private Display display = null;

	private Table table = null;

	private TableViewer viewer = null;

	private WritableList input = null;

	private BookViewerComparator comparator = null;

	private LibraryTest() {
		display = new Display();
		Realm.runWithDefault(SWTObservables.getRealm(display), this);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		LibraryTest libraryTest = new LibraryTest();
	}

	@Override
	public void run() {
		Shell shell = new Shell(display);
		shell.setLayout(new GridLayout());
		table = new Table(shell, SWT.FULL_SELECTION);
		table.setHeaderVisible(true);
		table.setLayoutData(new GridData(GridData.FILL_BOTH));
		viewer = new TableViewer(table);
		comparator = new BookViewerComparator();
		viewer.setComparator(comparator);
		createColumns();
		bindValues();
		for (TableItem tableItem : table.getItems()) {
			createBookReadTableEditor(tableItem);
		}
		for (TableColumn column : table.getColumns()) {
			column.pack();
		}
		shell.open();
		// The SWT event loop
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	private void createColumns() {
		TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
		final TableColumn column = viewerColumn.getColumn();
		viewerColumn.getColumn().setText("Title");
		viewerColumn.setLabelProvider(new ColumnLabelProvider() {

			@Override
			public String getText(Object element) {
				Book book = (Book) element;
				return book.title;
			}

		});
		viewerColumn.getColumn().addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				viewer.getTable().setSortColumn(column);
				viewer.getTable().setSortDirection(comparator.change());
				viewer.refresh();
			}

		});
		viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
		viewerColumn.getColumn().setText("Writers");
		viewerColumn.setLabelProvider(new ColumnLabelProvider() {

			@Override
			public String getText(Object element) {
				Book book = (Book) element;
				List<Writer> writers = book.getWriters();
				StringBuilder text = new StringBuilder();
				int iMax = writers.size() - 1;
				if (iMax == -1) {
					return "";
				}
				for (int i = 0;; i++) {
					Writer writer = writers.get(i);
					text.append(writer.getFirstName() + " "
							+ writer.getLastName());
					if (i == iMax) {
						break;
					}
					text.append(", ");
				}
				return text.toString();
			}

		});
		viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
		viewerColumn.getColumn().setText("Read?");
		viewerColumn.setLabelProvider(new ColumnLabelProvider() {

			@Override
			public String getText(Object element) {
				Book book = (Book) element;
				if (Boolean.TRUE.equals(book.getRead())) {
					return Boolean.TRUE.toString();
				}
				return Boolean.FALSE.toString();
			}

		});
	}

	private void bindValues() {
		createInput();
		viewer.setContentProvider(new ObservableListContentProvider(
				new IViewerUpdater() {

					@Override
					public void replace(Object oldElement, Object newElement,
							int position) {
					}

					@Override
					public void remove(Object element, int position) {
					}

					@Override
					public void remove(Object[] elements) {
					}

					@Override
					public void move(Object element, int oldPosition,
							int newPosition) {
					}

					@Override
					public void insert(Object element, int position) {
						viewer.insert(element, position);
						for (TableItem tableItem : table.getItems()) {
							if (element.equals(tableItem.getData())) {
								createBookReadTableEditor(tableItem);
								return;
							}
						}
					}

					@Override
					public void add(Object[] elements) {
					}
				}));
		viewer.setInput(input);
	}

	private void createInput() {
		List<Writer> writers = new ArrayList<Writer>();
		writers.add(new Writer("Johann Wolfgang", "von Goethe"));
		List<Book> books = new ArrayList<Book>();
		Book book = new Book("Faust: Der Tragödie erster Teil");
		book.setWriters(writers);
		books.add(book);
		writers = new ArrayList<Writer>();
		writers.add(new Writer("Joanne K.", "Rowling"));
		book = new Book("Harry Potter and the Philosopher's Stone");
		book.setRead(true);
		book.setWriters(writers);
		books.add(book);
		book = new Book("Harry Potter and the Chamber of Secrets");
		book.setWriters(writers);
		books.add(book);
		input = new WritableList(books, Book.class);
	}

	private void createBookReadTableEditor(TableItem tableItem) {
		final TableEditor editor = new TableEditor(table);
		final Button checkbox = new Button(table, SWT.CHECK);
		Book book = (Book) tableItem.getData();
		checkbox.setSelection(book.getRead() != null
				&& book.getRead().booleanValue());
		checkbox.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				Book book = (Book) editor.getItem().getData();
				book.setRead(Boolean.valueOf(checkbox.getSelection()));
			}

		});
		checkbox.pack();
		editor.minimumWidth = checkbox.getSize().x;
		editor.horizontalAlignment = SWT.LEFT;
		editor.setEditor(checkbox, tableItem, 2);
	}
}


Best regards!
Re: Problem sorting table with TableEditor item [message #697662 is a reply to message #697655] Sun, 17 July 2011 12:42 Go to previous messageGo to next message
Eclipse user Chennai is currently offline Eclipse user Chennai
Messages: 15
Registered: May 2011
Junior Member
Try with Sorter class for implementing sorting functionality. Also refresh viewer after adding each record.

~Barani.
Re: Problem sorting table with TableEditor item [message #698038 is a reply to message #697662] Mon, 18 July 2011 12:46 Go to previous messageGo to next message
Andreas Fagschlunger is currently offline Andreas Fagschlunger
Messages: 12
Registered: June 2011
Junior Member
Doesn't work either.

I tried this way:

class BookViewerComparator extends ViewerSorter {


viewer.setSorter(comparator);
// viewer.setComparator(comparator);


Sorting has an effect, but the checkboxes doesn't move with the TableItem's. So it is the same behaviour as using setComparator and so on still the same issue.
Re: Problem sorting table with TableEditor item [message #698102 is a reply to message #698038] Mon, 18 July 2011 15:06 Go to previous messageGo to next message
Andi Thomas is currently offline Andi Thomas
Messages: 38
Registered: July 2009
Member
i think the problem is the use of table editors to show the check boxes.

Check out this example.
http://wiki.eclipse.org/index.php/JFaceSnippets#Snippet061FakedNativeCellEditor


On 7/18/11 12:46 PM, Andreas Fagschlunger wrote:
> Doesn't work either.
>
> I tried this way:
>
> class BookViewerComparator extends ViewerSorter {
>
> viewer.setSorter(comparator);
> // viewer.setComparator(comparator);
>
> Sorting has an effect, but the checkboxes doesn't move with the
> TableItem's. So it is the same behaviour as using setComparator and so
> on still the same issue.
Re: Problem sorting table with TableEditor item [message #698548 is a reply to message #698102] Tue, 19 July 2011 12:45 Go to previous messageGo to next message
Andreas Fagschlunger is currently offline Andreas Fagschlunger
Messages: 12
Registered: June 2011
Junior Member
Here is my solution:

Keep references of TableItems and Checkboxes in a Map:

private Map<TableItem, Button> checkboxes = new HashMap<TableItem, Button>();

	private void createBookReadTableEditor(TableItem tableItem) {
		final TableEditor editor = new TableEditor(table);
		final Button checkbox = new Button(table, SWT.CHECK);
		checkboxes.put(tableItem, checkbox);
		...


And after sorting is applied and the viewer is refreshed I manually update the checkboxes:

		viewerColumn.getColumn().addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				viewer.getTable().setSortColumn(column);
				viewer.getTable().setSortDirection(comparator.change());
				viewer.refresh();
				for (TableItem tableItem : checkboxes.keySet()) {
					Book book = (Book) tableItem.getData();
					Button checkbox = checkboxes.get(tableItem);
					checkbox.setSelection(Boolean.TRUE.equals(book.getRead()));
				}
			}

		});

Re: Problem sorting table with TableEditor item [message #700320 is a reply to message #698548] Sat, 23 July 2011 02:51 Go to previous message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5262
Registered: July 2009
Senior Member
Useing TableEditor is not a good solution. See
http://wiki.eclipse.org/Tables_And_Trees_And_NativeControls for a
discussion on it.

The snippet referenced by Andi is the way to go and has been developed
exactly because of draw backs mentionned in the above wiki-entry.

Tom

Am 19.07.11 18:45, schrieb Andreas Fagschlunger:
> Here is my solution:
>
> Keep references of TableItems and Checkboxes in a Map:
>
>
> private Map<TableItem, Button> checkboxes = new HashMap<TableItem,
> Button>();
>
> private void createBookReadTableEditor(TableItem tableItem) {
> final TableEditor editor = new TableEditor(table);
> final Button checkbox = new Button(table, SWT.CHECK);
> checkboxes.put(tableItem, checkbox);
> ...
>
>
> And after sorting is applied and the viewer is refreshed I manually
> update the checkboxes:
>
>
> viewerColumn.getColumn().addSelectionListener(new
> SelectionAdapter() {
>
> @Override
> public void widgetSelected(SelectionEvent e) {
> viewer.getTable().setSortColumn(column);
> viewer.getTable().setSortDirection(comparator.change());
> viewer.refresh();
> for (TableItem tableItem : checkboxes.keySet()) {
> Book book = (Book) tableItem.getData();
> Button checkbox = checkboxes.get(tableItem);
>
> checkbox.setSelection(Boolean.TRUE.equals(book.getRead()));
> }
> }
>
> });
>
>
Previous Topic:Customizing JFace Wizard Layout
Next Topic:Changing background for FormText list items
Goto Forum:
  


Current Time: Fri Aug 01 20:28:02 EDT 2014

Powered by FUDForum. Page generated in 0.13593 seconds