我已经根据Vogella 的说明(转载如下)实现了 JFace 的 TableViewer 排序。碰巧排序仅在图形界面中进行(它没有反映在原始数据结构中),我需要按照它们在 GUI 中显示的顺序获取元素。
或者,反映原始数据结构中排序的实现也适合。
package de.vogella.jface.tableviewer.sorter;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import de.vogella.jface.tableviewer.model.Person;
public class MyViewerComparator extends ViewerComparator {
private int propertyIndex;
private static final int DESCENDING = 1;
private int direction = DESCENDING;
public MyViewerComparator() {
this.propertyIndex = 0;
direction = DESCENDING;
}
public int getDirection() {
return direction == 1 ? SWT.DOWN : SWT.UP;
}
public void setColumn(int column) {
if (column == this.propertyIndex) {
// Same column as last sort; toggle the direction
direction = 1 - direction;
} else {
// New column; do an ascending sort
this.propertyIndex = column;
direction = DESCENDING;
}
}
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
Person p1 = (Person) e1;
Person p2 = (Person) e2;
int rc = 0;
switch (propertyIndex) {
case 0:
rc = p1.getFirstName().compareTo(p2.getFirstName());
break;
case 1:
rc = p1.getLastName().compareTo(p2.getLastName());
break;
case 2:
rc = p1.getGender().compareTo(p2.getGender());
break;
case 3:
if (p1.isMarried() == p2.isMarried()) {
rc = 0;
} else
rc = (p1.isMarried() ? 1 : -1);
break;
default:
rc = 0;
}
// If descending order, flip the direction
if (direction == DESCENDING) {
rc = -rc;
}
return rc;
}
}
package de.vogella.jface.tableviewer;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
import de.vogella.jface.tableviewer.model.ModelProvider;
import de.vogella.jface.tableviewer.model.Person;
import de.vogella.jface.tableviewer.sorter.MyViewerComparator;
public class View extends ViewPart {
public static final String ID = "de.vogella.jface.tableviewer.view";
private MyViewerComparator comparator;
private TableViewer viewer;
// We use icons
private static final Image CHECKED = Activator.getImageDescriptor("icons/checked.gif").createImage();
private static final Image UNCHECKED = Activator.getImageDescriptor("icons/unchecked.gif").createImage();
public void createPartControl(Composite parent) {
GridLayout layout = new GridLayout(2, false);
parent.setLayout(layout);
Label searchLabel = new Label(parent, SWT.NONE);
searchLabel.setText("Search: ");
final Text searchText = new Text(parent, SWT.BORDER | SWT.SEARCH);
searchText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
| GridData.HORIZONTAL_ALIGN_FILL));
createViewer(parent);
// Set the sorter for the table
comparator = new MyViewerComparator();
viewer.setComparator(comparator);
}
private void createViewer(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
createColumns(parent, viewer);
final Table table = viewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
viewer.setContentProvider(new ArrayContentProvider());
// Get the content for the viewer, setInput will call getElements in the
// contentProvider
viewer.setInput(ModelProvider.INSTANCE.getPersons());
// Make the selection available to other views
getSite().setSelectionProvider(viewer);
// Layout the viewer
GridData gridData = new GridData();
gridData.verticalAlignment = GridData.FILL;
gridData.horizontalSpan = 2;
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
viewer.getControl().setLayoutData(gridData);
}
public TableViewer getViewer() {
return viewer;
}
// This will create the columns for the table
private void createColumns(final Composite parent, final TableViewer viewer) {
String[] titles = { "First name", "Last name", "Gender", "Married" };
int[] bounds = { 100, 100, 100, 100 };
// First column is for the first name
TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);
col.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
Person p = (Person) element;
return p.getFirstName();
}
});
// Second column is for the last name
col = createTableViewerColumn(titles[1], bounds[1], 1);
col.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
Person p = (Person) element;
return p.getLastName();
}
});
// Now the gender
col = createTableViewerColumn(titles[2], bounds[2], 2);
col.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
Person p = (Person) element;
return p.getGender();
}
});
// // Now the status married
col = createTableViewerColumn(titles[3], bounds[3], 3);
col.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
return null;
}
@Override
public Image getImage(Object element) {
if (((Person) element).isMarried()) {
return CHECKED;
} else {
return UNCHECKED;
}
}
});
}
private TableViewerColumn createTableViewerColumn(String title, int bound,
final int colNumber) {
final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(title);
column.setWidth(bound);
column.setResizable(true);
column.setMoveable(true);
column.addSelectionListener(getSelectionAdapter(column, colNumber));
return viewerColumn;
}
private SelectionAdapter getSelectionAdapter(final TableColumn column,
final int index) {
SelectionAdapter selectionAdapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
comparator.setColumn(index);
int dir = comparator.getDirection();
viewer.getTable().setSortDirection(dir);
viewer.getTable().setSortColumn(column);
viewer.refresh();
}
};
return selectionAdapter;
}
/** * Passing the focus request to the viewer's control. */
public void setFocus() {
viewer.getControl().setFocus();
}
}