/******************************************************************************* * Copyright (c) 2011 Google, Inc. * 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: * Google, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.wb.swt; import java.lang.reflect.Method; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerColumn; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Table; /** * Helper for sorting {@link TableViewer} by one of its {@link TableViewerColumn}s. * <p> * Originally from http://wiki.eclipse.org/index.php/JFaceSnippets, Snippet040TableViewerSorting. * * @author Tom Schindl <tom.schindl@bestsolution.at> * @author Konstantin Scheglov <Konstantin.Scheglov@gmail.com> */ public class TableViewerColumnSorter extends ViewerComparator { public static final int ASC = 1; public static final int NONE = 0; public static final int DESC = -1; // ////////////////////////////////////////////////////////////////////////// // // Instance fields // // ////////////////////////////////////////////////////////////////////////// private final TableViewerColumn m_column; private final TableViewer m_viewer; private final Table m_table; private int m_direction = NONE; // ////////////////////////////////////////////////////////////////////////// // // Constructor // // ////////////////////////////////////////////////////////////////////////// public TableViewerColumnSorter(TableViewerColumn column){ m_column = column; m_viewer = (TableViewer) column.getViewer(); m_table = m_viewer.getTable(); m_column.getColumn().addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e){ if (m_viewer.getComparator() != null) { if (m_viewer.getComparator() == TableViewerColumnSorter.this) { if (m_direction == ASC) { setSorter(DESC); } else if (m_direction == DESC) { setSorter(NONE); } } else { setSorter(ASC); } } else { setSorter(ASC); } } }); } // ////////////////////////////////////////////////////////////////////////// // // Utils // // ////////////////////////////////////////////////////////////////////////// public void setSorter(int direction){ if (direction == NONE) { m_table.setSortColumn(null); m_table.setSortDirection(SWT.NONE); m_viewer.setComparator(null); } else { m_table.setSortColumn(m_column.getColumn()); m_direction = direction; if (m_direction == ASC) { m_table.setSortDirection(SWT.DOWN); } else { m_table.setSortDirection(SWT.UP); } if (m_viewer.getComparator() == this) { m_viewer.refresh(); } else { m_viewer.setComparator(this); } } } // ////////////////////////////////////////////////////////////////////////// // // ViewerComparator // // ////////////////////////////////////////////////////////////////////////// public int compare(Viewer viewer, Object e1, Object e2){ return m_direction * doCompare(viewer, e1, e2); } /** * Compares to elements of viewer. By default tries to compare values extracted from these * elements using {@link #getValue(Object)}, because usually you want to compare value of some * attribute. */ @SuppressWarnings("unchecked") protected int doCompare(Viewer viewer, Object e1, Object e2){ Object o1 = getValue(e1); Object o2 = getValue(e2); if (o1 instanceof Comparable && o2 instanceof Comparable) { return ((Comparable) o1).compareTo(o2); } return 0; } /** * * @return the value to compare in {@link #doCompare(Viewer, Object, Object)}. Be default tries * to get it from {@link EditingSupport}. May return <code>null</code>. */ protected Object getValue(Object o){ try { EditingSupport editingSupport; { Method getEditingMethod = ViewerColumn.class.getDeclaredMethod("getEditingSupport", new Class[] {}); getEditingMethod.setAccessible(true); editingSupport = (EditingSupport) getEditingMethod.invoke(m_column, new Object[] {}); } if (editingSupport != null) { Method getValueMethod = EditingSupport.class.getDeclaredMethod("getValue", new Class[] { Object.class }); getValueMethod.setAccessible(true); return getValueMethod.invoke(editingSupport, new Object[] { o }); } } catch (Throwable e) {} return null; } }