| Java, Eclipse and Web programming Tutorials |
Version 1.8
Copyright © 2008 - 2009 Lars Vogel
16.12.2009
| Revision History | ||
|---|---|---|
| Revision 0.1 | 01.07.2007 | Clemens Muessener |
| Created Article | ||
| Revision 0.2 | 12.09.2007 | Lars Vogel |
| Revised Article | ||
| Revision 0.3 | 20.03.2008 | Hendrik Still |
| Added Editors, navigation via tab | ||
| Revision 0.4 | 12.10.2008 | Marcus Rieck |
| Added Sort Columns / Show Hide Columns and | ||
| Revision 0.5 | 21.03.2009 | Lars Vogel |
| Re-worked article, added explanation about the general concept of JFace | ||
| Revision 0.6 | 22.03.2009 | Lars Vogel |
| Correct usage of setInput() in View.java | ||
| Revision 0.7 | 23.03.2009 | Lars Vogel |
| Changed project and package name | ||
| Revision 0.8 | 24.03.2009 | Lars Vogel |
| Fixed the sorter coding | ||
| Revision 0.9 | 29.03.2009 | Lars Vogel |
| Added filter | ||
| Revision 1.0 | 30.03.2009 | Lars Vogel |
| Added StyledCellLabelProvider | ||
| Revision 1.1 | 20.04.2009 | Lars Vogel |
| Minor clean-up in PersonEditingSupport | ||
| Revision 1.2 | 20.05.2009 | Lars Vogel |
| Show / Hide using the menu on the table using Eclipse 3.5 | ||
| Revision 1.3 | 27.07.2009 | Lars Vogel |
| Fixed StyledLabelProvider | ||
| Revision 1.4 | 05.08.2009 | Lars Vogel |
| Fixed sorter for Persons | ||
| Revision 1.5 | 02.09.2009 | Lars Vogel |
| removed hard-coded image location against Activator.getImageDescriptor() | ||
| Revision 1.6 | 08.09.2009 | Lars Vogel |
| Fixed incorrect import in LabelProvider | ||
| Revision 1.7 | 10.09.2009 | Lars Vogel |
| added TreeNodeContentProvider and LabelProvider explanation | ||
| Revision 1.8 | 16.12.2009 | Lars Vogel |
| LabelProvider is also template for ITableLabelProvider | ||
Table of Contents
Eclipse JFace viewers allow to display a domain model in a list, tree or table without converting the domain model beforehand.
These viewers provider adaptors which are used to provide the model to the viewer (these are called content provider) and adaptors to define how the model data is displayed in the viewer (these are called label providers).
The Eclipse JFace viewer concept is very flexible as it allows to use the same content provider / label provider in different viewers without changing the underlying data structure.
JFace also allows assign label provider directly to columns instead of one label provider for the whole table.
In working with JFace viewers it is important to understand the concept of viewers, label and content providers. The following provides an overview and lists some typical classes in these areas.
The user interface is represented by the viewer, e.g. in our example the table viewer.
Viewer: Typical viewers are
org.eclipse.jface.viewers.ListViewer - Display a simple list
org.eclipse.jface.viewers.TreeViewer - Displays a tree
org.eclipse.jface.viewers.TableViewer - Displays a table
Responsible for providing objects to the view. It can simply return objects as-is.
Typical content provider are
IStructuredContentProvider: Used for lists and tables
ITreeContentProvider: Used for trees, has addional methods to determine the children and the parents of elements
Defines how objects are displayed, e.g. which part of the object is used to return the text which is displayed.
Label provider follow usually the template approach; you have an interface which describes and contact and a class which the programmer can use which delivers already reasonable implementations for the interface and the programmer can then choose to override only the relevant methods.
Typical label providers are
Table 1. Label providers
| Interface | Template class | Description |
|---|---|---|
| ILabelProvider | LabelProvider | Used for lists and trees, displays per element a icons and / or a text element. |
| ITableLabelProvider | LabelProvider | Used for tables, displays per element and column a icons and / or a text element |
In this tutorial we will build a Eclipse RCP application which will display a domain model in a JFace table. The domain modelrepresents the data of persons (first name, last name, gender and if he/she is married). Each person is displayed in one row in the table.
Different editors and label provider will be used for different data types. The article demonstrate how to sort based on different table columns and how to use filters to display only selected content of the viewer. We will then learn how to use StyledCellLabelProvider to influence the display of data in the table. The usage of commands and how to hide and sort table columns is demonstrated.
The application will also be able to change the first name and last name like a text editor, the gender by a drop down list and the married status by a checkbox. You can edit the objects on two ways: an inline editor in the table and within a editor.
Via the menu it will be possible to add new persons to the table and to remove persons from the table. You will also be able to show/hide columns.
The final application will look like this.

Create a new RCP Project "de.vogella.jface.tableviewer" (see Create your first Eclipse RCP application for details). Use the "RCP application with a view" as a template.
Create a package "de.vogella.jface.tableviewer.model".
Create the following class "Person". This class contains the first name, last name, gender and married status for a person and represents the data model for this example.
package de.vogella.jface.tableviewer.model;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class Person {
private String firstName;
private String lastName;
private boolean married;
private String gender;
private Integer age;
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
this);
public Person() {
}
public Person(String firstName, String lastName, String gender,
boolean married) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
this.married = married;
}
public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public String getFirstName() {
return firstName;
}
public String getGender() {
return gender;
}
public String getLastName() {
return lastName;
}
public boolean isMarried() {
return married;
}
public void setFirstName(String firstName) {
propertyChangeSupport.firePropertyChange("firstName", this.firstName,
this.firstName = firstName);
}
public void setGender(String gender) {
propertyChangeSupport.firePropertyChange("gender", this.gender,
this.gender = gender);
}
public void setLastName(String lastName) {
propertyChangeSupport.firePropertyChange("lastName", this.lastName,
this.lastName = lastName);
}
public void setMarried(boolean isMarried) {
propertyChangeSupport.firePropertyChange("married", this.married,
this.married = isMarried);
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
propertyChangeSupport.firePropertyChange("age", this.age,
this.age = age);
}
@Override
public String toString() {
return firstName + " " + lastName;
}
}
Now create a class, called "ModelProvider". This class will be providing the collection of persons. This class is defined as a Singleton (see The Singleton Pattern for details).
package de.vogella.jface.tableviewer.model;
import java.util.ArrayList;
import java.util.List;
public class ModelProvider {
private static ModelProvider content;
private List<Person> persons;
private ModelProvider() {
persons = new ArrayList<Person>();
// Image here some fancy database access to read the persons and to
// put them into the model
Person person;
person = new Person("Rainer", "Zufall", "male", true);
persons.add(person);
person = new Person("Rainer", "Babbel", "male", true);
persons.add(person);
person = new Person("Marie", "Darms", "female", false);
persons.add(person);
person = new Person("Holger", "Adams", "male", true);
persons.add(person);
person = new Person("Juliane", "Adams", "female", true);
persons.add(person);
}
public static synchronized ModelProvider getInstance() {
if (content != null) {
return content;
}
content = new ModelProvider();
return content;
}
public List<Person> getPersons() {
return persons;
}
}
The application you have created already contains a pre-defined view. This is because we used the template "RCP application with a view". In this view a content provider and a label provider are given and assigned to a table viewer. Open now the class View.java and review and the method "createPartControl".
The following will replace these default providers with our own providers.
Create your own Content Provider. First create the package "de.vogella.jface.tableviewer.providers". Create the class "PersonContentProvider" which implement the Interface "org.eclipse.jface.viewers.IStructuredContentProvider".
We use the classes "ControlPersons" and "Person" to save the data model. The main purpose of the class "MyContentProvider" is to read the data model and to return the data as an array.
package de.vogella.jface.tableviewer.providers;
import java.util.List;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;
import de.vogella.jface.tableviewer.model.Person;
public class PersonContentProvider implements IStructuredContentProvider {
@Override
public Object[] getElements(Object inputElement) {
@SuppressWarnings("unchecked")
List<Person> persons = (List<Person>) inputElement;
return persons.toArray();
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
The method getElements() will be called by the viewer. The viewer has method setInput(). This input will be provided to the contentProvider as the parameter in method getElements().
We will use icons for the married Status. If the folder "icons" does not exists in your project create it. Download the icons from the link provided at the end of this article and place the two icons in the folder icons.
The class "View" already contains a Label Provider from the example. Currently the toString() method of the object Person is used in this label provider. We will replace this default label provider with our own label providers.
Create class "PersonLabelProvider" implementing the interface org.eclipse.jface.viewers.ITableLabelProvider.
package de.vogella.jface.tableviewer.providers;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import de.vogella.jface.tableviewer.Activator;
import de.vogella.jface.tableviewer.model.Person;
public class PersonLabelProvider extends LabelProvider implements
ITableLabelProvider {
// We use icons
// 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();
@Override
public Image getColumnImage(Object element, int columnIndex) {
// In case you don't like image just return null here
if (columnIndex == 3) {
if (((Person) element).isMarried()) {
return CHECKED;
} else {
return UNCHECKED;
}
}
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
Person person = (Person) element;
switch (columnIndex) {
case 0:
return person.getFirstName();
case 1:
return person.getLastName();
case 2:
return person.getGender();
case 3:
return String.valueOf(person.isMarried());
default:
throw new RuntimeException("Should not happen");
}
}
}
Important thing to note:
getColumnText: will return the value for a certain element, e.g. in our example row and column. May not be null.
getColumnImage: will return the image for a certain element and a certain column. May be null
We have to change the class "View.java" to use our content and label providers. We will also delete the internal class ViewLabelProvider and ViewContentProvider which the tempate generated.
package de.vogella.jface.tableviewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.part.ViewPart;
import de.vogella.jface.tableviewer.model.ModelProvider;
import de.vogella.jface.tableviewer.providers.PersonContentProvider;
import de.vogella.jface.tableviewer.providers.PersonLabelProvider;
public class View extends ViewPart {
public static final String ID = "de.vogella.jface.tableviewer.view";
private TableViewer viewer;
public void createPartControl(Composite parent) {
createViewer(parent);
// Get the content for the viewer, setInput will call getElements in the
// contentProvider
viewer.setInput(ModelProvider.getInstance().getPersons());
}
private void createViewer(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.FULL_SELECTION);
createColumns(viewer);
viewer.setContentProvider(new PersonContentProvider());
viewer.setLabelProvider(new PersonLabelProvider());
}
// This will create the columns for the table
private void createColumns(TableViewer viewer) {
String[] titles = { "First name", "Last name", "Gender", "Married" };
int[] bounds = { 100, 100, 100, 100 };
for (int i = 0; i < titles.length; i++) {
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText(titles[i]);
column.getColumn().setWidth(bounds[i]);
column.getColumn().setResizable(true);
column.getColumn().setMoveable(true);
}
Table table = viewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
}
The method createColumns create the table columns, headers, sets the size of the columns, makes the columns resizable and show the lines in the table.
A cell editor defines how the user can edit certain cells of a table.
We will define the editors for our table. The "First name" and "Last name" column will be editable by a textfield. The "Gende"’ column will be editable by a drop down list and the "Married" column will be editable by a checkbox.
Create a new class with the name "PersonEditingSupport" in package de.vogella.jface.tableviewer.providers.
package de.vogella.jface.tableviewer.providers;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import de.vogella.jface.tableviewer.model.Person;
public class PersonEditingSupport extends EditingSupport {
private CellEditor editor;
private int column;
public PersonEditingSupport(ColumnViewer viewer, int column) {
super(viewer);
String[] gender = new String[2];
gender[0] = "male";
gender[1] = "female";
// Create the correct editor based on the column index
switch (column) {
case 2:
editor = new ComboBoxCellEditor(((TableViewer) viewer).getTable(),
gender);
break;
case 3:
editor = new CheckboxCellEditor(null, SWT.CHECK | SWT.READ_ONLY);
break;
default:
editor = new TextCellEditor(((TableViewer) viewer).getTable());
}
this.column = column;
}
@Override
protected boolean canEdit(Object element) {
return true;
}
@Override
protected CellEditor getCellEditor(Object element) {
return editor;
}
@Override
protected Object getValue(Object element) {
Person person = (Person) element;
switch (this.column) {
case 0:
return person.getFirstName();
case 1:
return person.getLastName();
case 2:
if (person.getGender().equals("male")) {
return 0;
}
return 1;
case 3:
return person.isMarried();
default:
break;
}
return null;
}
@Override
protected void setValue(Object element, Object value) {
Person pers = (Person) element;
switch (this.column) {
case 0:
pers.setFirstName(String.valueOf(value));
break;
case 1:
pers.setLastName(String.valueOf(value));
break;
case 2:
if (((Integer) value) == 0) {
pers.setGender("male");
} else {
pers.setGender("female");
}
break;
case 3:
pers.setMarried((Boolean) value);
break;
default:
break;
}
getViewer().update(element, null);
}
}
Explanation of the the main methods of "PersonEditingSupport":
‘getCellEditor’ : In this method you return the celleditor you want to use (e.g. Texteditor). I work with a ‘switch-case-command’ to split my columns and give every column its own celleditor.
‘setValue’: Receives the new value the user gives. You have to set the new value to the object which is given, too.
‘getValue’: Receives the object which was changed and returns the value for the table. You have to return the new value of the object.
Now assign the editors to your columns. We do this in View.java in the method createColumns().
// This will create the columns for the table
private void createColumns(TableViewer viewer) {
String[] titles = { "First name", "Last name", "Gender", "Married" };
int[] bounds = { 100, 100, 100, 100 };
for (int i = 0; i < titles.length; i++) {
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText(titles[i]);
column.getColumn().setWidth(bounds[i]);
column.getColumn().setResizable(true);
column.getColumn().setMoveable(true);
// enable editing support
column.setEditingSupport(new PersonEditingSupport(viewer, i));
}
Table table = viewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
}
Run now your application. You should now be able to modify the content of the JFace table.

This chapter explains how to to sort the columns of the table ascending/descending.
Create a new Class "de.vogella.jface.tableviewer.sorter.TableSorter.java"
package de.vogella.jface.tableviewer.sorter;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import de.vogella.jface.tableviewer.model.Person;
public class TableSorter extends ViewerSorter {
private int propertyIndex;
// private static final int ASCENDING = 0;
private static final int DESCENDING = 1;
private int direction = DESCENDING;
public TableSorter() {
this.propertyIndex = 0;
direction = DESCENDING;
}
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;
}
}
Add a listener to the view for setting the information which column should be sorted. Change View.java to the following-
package de.vogella.jface.tableviewer;
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.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.part.ViewPart;
import de.vogella.jface.tableviewer.model.ModelProvider;
import de.vogella.jface.tableviewer.providers.PersonContentProvider;
import de.vogella.jface.tableviewer.providers.PersonEditingSupport;
import de.vogella.jface.tableviewer.providers.PersonLabelProvider;
import de.vogella.jface.tableviewer.sorter.TableSorter;
public class View extends ViewPart {
public static final String ID = "de.vogella.jface.tableviewer.view";
private TableViewer viewer;
private TableSorter tableSorter;
public void createPartControl(Composite parent) {
createViewer(parent);
// Get the content for the viewer, setInput will call getElements in the
// contentProvider
viewer.setInput(ModelProvider.getInstance().getPersons());
// Make the selection available
getSite().setSelectionProvider(viewer);
// Set the sorter for the table
tableSorter = new TableSorter();
viewer.setSorter(tableSorter);
}
private void createViewer(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.FULL_SELECTION);
createColumns(viewer);
viewer.setContentProvider(new PersonContentProvider());
viewer.setLabelProvider(new PersonLabelProvider());
}
public TableViewer getViewer() {
return viewer;
}
// This will create the columns for the table
private void createColumns(final TableViewer viewer) {
Table table = viewer.getTable();
String[] titles = { "First name", "Last name", "Gender", "Married" };
int[] bounds = { 100, 100, 100, 100 };
for (int i = 0; i < titles.length; i++) {
final int index = i;
final TableViewerColumn viewerColumn = new TableViewerColumn(
viewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(titles[i]);
column.setWidth(bounds[i]);
column.setResizable(true);
column.setMoveable(true);
// Setting the right sorter
column.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
tableSorter.setColumn(index);
int dir = viewer.getTable().getSortDirection();
if (viewer.getTable().getSortColumn() == column) {
dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
} else {
dir = SWT.DOWN;
}
viewer.getTable().setSortDirection(dir);
viewer.getTable().setSortColumn(column);
viewer.refresh();
}
});
viewerColumn.setEditingSupport(new PersonEditingSupport(viewer, i));
}
table.setHeaderVisible(true);
table.setLinesVisible(true);
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
}
Run the example, click on a column, there will appear a sort-direction signifier and your items are ordered ascending or descending.
Now we would like to add a filter to the table. The user should have a text field in which we can enter a first- or lastname. Only the names which applies to this filter should get displayed.
Adding a filter to a view is simple, you use method addFilter() on the viewer, which expects a ViewFilter as argument. Each ViewFilter is checked the input on the viewer is changed of whenever the viewer.refresh();
Create a new Class "de.vogella.jface.tableviewer.filter.PersonFilter.java"
package de.vogella.jface.tableviewer.filter;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import de.vogella.jface.tableviewer.model.Person;
public class PersonFilter extends ViewerFilter {
private String searchString;
public void setSearchText(String s) {
// Search must be a substring of the existing value
this.searchString = ".*" + s + ".*";
}
@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (searchString == null || searchString.length() == 0) {
return true;
}
Person p = (Person) element;
if (p.getFirstName().matches(searchString)) {
return true;
}
if (p.getLastName().matches(searchString)) {
return true;
}
return false;
}
}
We will create a new text field in which the user can search. This text field will have a keyListener which updates the filter and the viewer. Change the View.java to the following .
package de.vogella.jface.tableviewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.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.filter.PersonFilter;
import de.vogella.jface.tableviewer.model.ModelProvider;
import de.vogella.jface.tableviewer.providers.PersonContentProvider;
import de.vogella.jface.tableviewer.providers.PersonEditingSupport;
import de.vogella.jface.tableviewer.providers.PersonLabelProvider;
import de.vogella.jface.tableviewer.sorter.TableSorter;
public class View extends ViewPart {
public static final String ID = "de.vogella.jface.tableviewer.view";
private TableViewer viewer;
private TableSorter tableSorter;
private PersonFilter filter;
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));
searchText.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
filter.setSearchText(searchText.getText());
viewer.refresh();
}
});
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
createColumns(viewer);
viewer.setContentProvider(new PersonContentProvider());
viewer.setLabelProvider(new PersonLabelProvider());
// Get the content for the viewer, setInput will call getElements in the
// contentProvider
viewer.setInput(ModelProvider.getInstance().getPersons());
// Make the selection available
getSite().setSelectionProvider(viewer);
// Set the sorter for the table
tableSorter = new TableSorter();
viewer.setSorter(tableSorter);
filter = new PersonFilter();
viewer.addFilter(filter);
// 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 TableViewer viewer) {
Table table = viewer.getTable();
String[] titles = { "First name", "Last name", "Gender", "Married" };
int[] bounds = { 100, 100, 100, 100 };
for (int i = 0; i < titles.length; i++) {
final int index = i;
final TableViewerColumn viewerColumn = new TableViewerColumn(
viewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(titles[i]);
column.setWidth(bounds[i]);
column.setResizable(true);
column.setMoveable(true);
// Setting the right sorter
column.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
tableSorter.setColumn(index);
int dir = viewer.getTable().getSortDirection();
if (viewer.getTable().getSortColumn() == column) {
dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
} else {
dir = SWT.DOWN;
}
viewer.getTable().setSortDirection(dir);
viewer.getTable().setSortColumn(column);
viewer.refresh();
}
});
viewerColumn.setEditingSupport(new PersonEditingSupport(viewer, i));
}
table.setHeaderVisible(true);
table.setLinesVisible(true);
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
}
Run the example, filtering should work.
It is also possible to use a StyleCellLabelProvider to highlight the search result. StyleCellLabelProvider can do much more but we will look at the simple case.
First create the following helper class which will determine which occurrence of the search string is in the column.
package de.vogella.jface.tableviewer.util;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.widgets.Display;
public class SearchUtil {
public static int[] getSearchTermOccurrences(String searchTerm,
String content) {
List<StyleRange> styleRange;
List<Integer> ranges;
Display disp = Display.getCurrent();
StyleRange myStyleRange = new StyleRange(0, 0, null, disp
.getSystemColor(SWT.COLOR_YELLOW));
styleRange = new ArrayList<StyleRange>(); // reset the StyleRange-Array
// for each new field
ranges = new ArrayList<Integer>(); // reset the ranges-array
// empty search term ==> return an empty StyleRange array
if (searchTerm.equals("")) {
return new int[] {};
}
// determine all occurrences of the searchText and write the beginning
// and length of each occurrence into an array
for (int i = 0; i < content.length(); i++) {
if (i + searchTerm.length() <= content.length()
&& content.substring(i, i + searchTerm.length())
.equalsIgnoreCase(searchTerm)) {
// ranges format: n->start of the range, n+1->length of the
// range
ranges.add(i);
ranges.add(searchTerm.length());
}
}
// convert the list into an int[] and make sure that overlapping
// search term occurrences are are merged
int[] intRanges = new int[ranges.size()];
int arrayIndexCounter = 0;
for (int listIndexCounter = 0; listIndexCounter < ranges.size(); listIndexCounter++) {
if (listIndexCounter % 2 == 0) {
if (searchTerm.length() > 1
&& listIndexCounter != 0
&& ranges.get(listIndexCounter - 2)
+ ranges.get(listIndexCounter - 1) >= ranges
.get(listIndexCounter)) {
intRanges[arrayIndexCounter - 1] = 0
- ranges.get(listIndexCounter - 2)
+ ranges.get(listIndexCounter)
+ ranges.get(++listIndexCounter);
} else {
intRanges[arrayIndexCounter++] = ranges
.get(listIndexCounter);
}
} else {
intRanges[arrayIndexCounter++] = ranges.get(listIndexCounter);
styleRange.add(myStyleRange);
}
}
// if there have been any overlappings we need to reduce the size of
// the array to avoid conflicts in the setStyleRanges method
int[] intRangesCorrectSize = new int[arrayIndexCounter];
System.arraycopy(intRanges, 0, intRangesCorrectSize, 0,
arrayIndexCounter);
return intRangesCorrectSize;
}
}
Change your PersonLabelProvider to the following.
package de.vogella.jface.tableviewer.providers;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import de.vogella.jface.tableviewer.Activator;
import de.vogella.jface.tableviewer.model.Person;
import de.vogella.jface.tableviewer.util.SearchUtil;
public class PersonLabelProvider extends StyledCellLabelProvider {
// 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();
private String searchText;
private Color systemColor;
public PersonLabelProvider() {
systemColor = Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);
}
public void setSearchText(String searchText) {
this.searchText = searchText;
}
@Override
public void update(ViewerCell cell) {
Person element = (Person) cell.getElement();
int index = cell.getColumnIndex();
String columnText = getColumnText(element, index);
cell.setText(columnText);
cell.setImage(getColumnImage(element, index));
if (searchText != null && searchText.length() > 0) {
int intRangesCorrectSize[] = SearchUtil.getSearchTermOccurrences(
searchText, columnText);
List<StyleRange> styleRange = new ArrayList<StyleRange>();
for (int i = 0; i < intRangesCorrectSize.length / 2; i++) {
StyleRange myStyleRange = new StyleRange(0, 0, null,
systemColor);
myStyleRange.start = intRangesCorrectSize[i];
myStyleRange.length = intRangesCorrectSize[++i];
styleRange.add(myStyleRange);
}
cell.setStyleRanges(styleRange.toArray(new StyleRange[styleRange
.size()]));
} else {
cell.setStyleRanges(null);
}
super.update(cell);
}
private String getColumnText(Object element, int columnIndex) {
Person person = (Person) element;
switch (columnIndex) {
case 0:
return person.getFirstName();
case 1:
return person.getLastName();
case 2:
return person.getGender();
case 3:
return String.valueOf(person.isMarried());
default:
throw new RuntimeException("Should not happen");
}
}
private Image getColumnImage(Object element, int columnIndex) {
// In case you don't like image just return null here
if (columnIndex == 3) {
if (((Person) element).isMarried()) {
return CHECKED;
}
return UNCHECKED;
}
return null;
}
}
Make the following changes to the View. .
package de.vogella.jface.tableviewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.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.filter.PersonFilter;
import de.vogella.jface.tableviewer.model.ModelProvider;
import de.vogella.jface.tableviewer.providers.PersonContentProvider;
import de.vogella.jface.tableviewer.providers.PersonEditingSupport;
import de.vogella.jface.tableviewer.providers.PersonLabelProvider;
import de.vogella.jface.tableviewer.sorter.TableSorter;
public class View extends ViewPart {
public static final String ID = "de.vogella.jface.tableviewer.view";
private TableViewer viewer;
private TableSorter tableSorter;
private PersonFilter filter;
private PersonLabelProvider labelProvider;
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));
searchText.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
filter.setSearchText(searchText.getText());
labelProvider.setSearchText(searchText.getText());
viewer.refresh();
}
});
createViewer(parent);
// Get the content for the viewer, setInput will call getElements in the
// contentProvider
viewer.setInput(ModelProvider.getInstance().getPersons());
// Make the selection available
getSite().setSelectionProvider(viewer);
// Set the sorter for the table
tableSorter = new TableSorter();
viewer.setSorter(tableSorter);
filter = new PersonFilter();
viewer.addFilter(filter);
// 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);
}
private void createViewer(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
createColumns(viewer);
viewer.setContentProvider(new PersonContentProvider());
labelProvider = new PersonLabelProvider();
viewer.setLabelProvider(labelProvider);
}
public TableViewer getViewer() {
return viewer;
}
// This will create the columns for the table
private void createColumns(final TableViewer viewer) {
Table table = viewer.getTable();
String[] titles = { "First name", "Last name", "Gender", "Married" };
int[] bounds = { 100, 100, 100, 100 };
for (int i = 0; i < titles.length; i++) {
final int index = i;
final TableViewerColumn viewerColumn = new TableViewerColumn(
viewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(titles[i]);
column.setWidth(bounds[i]);
column.setResizable(true);
column.setMoveable(true);
// Setting the right sorter
column.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
tableSorter.setColumn(index);
int dir = viewer.getTable().getSortDirection();
if (viewer.getTable().getSortColumn() == column) {
dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
} else {
dir = SWT.DOWN;
}
viewer.getTable().setSortDirection(dir);
viewer.getTable().setSortColumn(column);
viewer.refresh();
}
});
viewerColumn.setEditingSupport(new PersonEditingSupport(viewer, i));
}
table.setHeaderVisible(true);
table.setLinesVisible(true);
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
}
Run the example, if you search now the selected content should get highlighted should work.
This chapter shows how to implement a menu on the table which allows to show and hide columns of the table. Please note that Eclipse 3.5 introduced the possibility to add menus to columns headers.
Change your coding in View.java to the following.
package de.vogella.jface.tableviewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
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.filter.PersonFilter;
import de.vogella.jface.tableviewer.model.ModelProvider;
import de.vogella.jface.tableviewer.providers.PersonContentProvider;
import de.vogella.jface.tableviewer.providers.PersonEditingSupport;
import de.vogella.jface.tableviewer.providers.PersonLabelProvider;
import de.vogella.jface.tableviewer.sorter.TableSorter;
public class View extends ViewPart {
public static final String ID = "de.vogella.jface.tableviewer.view";
private TableViewer viewer;
private TableSorter tableSorter;
private PersonFilter filter;
private PersonLabelProvider labelProvider;
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));
searchText.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
filter.setSearchText(searchText.getText());
labelProvider.setSearchText(searchText.getText());
viewer.refresh();
}
});
createViewer(parent);
}
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);
viewer.setContentProvider(new PersonContentProvider());
labelProvider = new PersonLabelProvider();
viewer.setLabelProvider(labelProvider);
// Get the content for the viewer, setInput will call getElements in the
// contentProvider
viewer.setInput(ModelProvider.getInstance().getPersons());
// Make the selection available
getSite().setSelectionProvider(viewer);
// Set the sorter for the table
tableSorter = new TableSorter();
viewer.setSorter(tableSorter);
filter = new PersonFilter();
viewer.addFilter(filter);
// 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) {
final Menu headerMenu = new Menu(parent);
String[] titles = { "First name", "Last name", "Gender", "Married" };
int[] bounds = { 100, 100, 100, 100 };
for (int i = 0; i < titles.length; i++) {
final int index = i;
final TableViewerColumn viewerColumn = new TableViewerColumn(
viewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(titles[i]);
column.setWidth(bounds[i]);
column.setResizable(true);
createMenuItem(headerMenu, column); // Create the menu item for this
// column
column.setMoveable(true);
// Setting the right sorter
column.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
tableSorter.setColumn(index);
int dir = viewer.getTable().getSortDirection();
if (viewer.getTable().getSortColumn() == column) {
dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
} else {
dir = SWT.DOWN;
}
viewer.getTable().setSortDirection(dir);
viewer.getTable().setSortColumn(column);
viewer.refresh();
}
});
viewerColumn.setEditingSupport(new PersonEditingSupport(viewer, i));
}
final Table table = viewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.addListener(SWT.MenuDetect, new Listener() {
public void handleEvent(Event event) {
table.setMenu(headerMenu);
}
});
}
private void createMenuItem(Menu parent, final TableColumn column) {
final MenuItem itemName = new MenuItem(parent, SWT.CHECK);
itemName.setText(column.getText());
itemName.setSelection(column.getResizable());
itemName.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if (itemName.getSelection()) {
column.setWidth(150);
column.setResizable(true);
} else {
column.setWidth(0);
column.setResizable(false);
}
}
});
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
}
If you run your application you are able to hide and show columns using the right mouse click on your table.
The following will demonstrate the usage of commands. Feel free to skip with chapter.
This chapter add the functionality to print the content of the domain model to the console. This way it is possible to verify that the changes on the JFace table are updating the model.
Create the command "de.vogella.jface.tableviewer.commands.Print" with the default handler "de.vogella.jface.tableviewer.commands.Print" (see Defining commands for details).
Implement the following coding:
package de.vogella.jface.tableviewer.commands;
import java.util.List;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import de.vogella.jface.tableviewer.model.ModelProvider;
import de.vogella.jface.tableviewer.model.Person;
public class Print extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
List<Person> personList = ModelProvider.getInstance().getPersons();
for (Person p : personList) {
System.out.println(p);
}
return null;
}
}
Add your command to the menu.(see Defining commands for details).
After finishing this you will be able to print the current state of your domain model to the console via the menu. Validate that the changes you are doing in the UI are reflected the model.
This chapter shows how to add and delete Persons to and from the table.
You have to make the selection of the viewer available and will also provide an access method to the viewer of the view.
public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.FULL_SELECTION);
createColumns(viewer);
viewer.setContentProvider(new PersonContentProvider());
viewer.setLabelProvider(new PersonLabelProvider());
// Get the content for the viewer, setInput will call getElements in the
// contentProvider
viewer.setInput(ModelProvider.getInstance().getPersons());
// Make the selection available
getSite().setSelectionProvider(viewer);
}
public TableViewer getViewer() {
return viewer;
}
Create the command "de.vogella.jface.tableviewer.commands.AddPerson" with the default handler "de.vogella.jface.tableviewer.commands.AddPerson". Add the command to your menu. Again see Defining commands for details.
Create a dialog to maintain the data for the additional person. Create package "de.vogella.jface.tableviewer.dialogs" and the following class "AddPersonDialog".
package de.vogella.jface.tableviewer.dialogs;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import de.vogella.jface.tableviewer.model.Person;
public class AddPersonDialog extends TitleAreaDialog {
private Text text1;
private Text text2;
private Person person;
private Button button1;
private Combo combo1;
public Person getPerson() {
return person;
}
public AddPersonDialog(Shell parentShell) {
super(parentShell);
}
@Override
protected Control createContents(Composite parent) {
Control contents = super.createContents(parent);
setTitle("Add a new Person");
setMessage("Please enter the data of the new person",
IMessageProvider.INFORMATION);
return contents;
}
@Override
protected Control createDialogArea(Composite parent) {
GridLayout layout = new GridLayout();
layout.numColumns = 2;
parent.setLayout(layout);
Label label1 = new Label(parent, SWT.NONE);
label1.setText("First Name");
text1 = new Text(parent, SWT.BORDER);
Label label2 = new Label(parent, SWT.NONE);
label2.setText("Last Name");
text2 = new Text(parent, SWT.BORDER);
Label label3 = new Label(parent, SWT.NONE);
label3.setText("Gender");
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
gd.horizontalSpan = 2;
combo1 = new Combo(parent, SWT.READ_ONLY);
combo1.add("male");
combo1.add("female");
button1 = new Button(parent, SWT.CHECK);
button1.setText("Is married?");
button1.setLayoutData(gd);
return parent;
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
((GridLayout) parent.getLayout()).numColumns++;
Button button = new Button(parent, SWT.PUSH);
button.setText("OK");
button.setFont(JFaceResources.getDialogFont());
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (text1.getText().length() != 0
&& text2.getText().length() != 0
&& combo1.getItem(combo1.getSelectionIndex()).length() != 0) {
person = new Person(text1.getText(), text2.getText(),
combo1.getItem(combo1.getSelectionIndex()), button1
.getSelection());
close();
} else {
setErrorMessage("Please enter all data");
}
}
});
}
}
Implement the following code for the class "de.vogella.jface.tableviewer.commands.AddPerson":
package de.vogella.jface.tableviewer.commands;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import de.vogella.jface.tableviewer.View;
import de.vogella.jface.tableviewer.dialogs.AddPersonDialog;
import de.vogella.jface.tableviewer.model.ModelProvider;
public class AddPerson extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
ModelProvider persons = ModelProvider.getInstance();
AddPersonDialog dialog = new AddPersonDialog(window.getShell());
dialog.open();
if (dialog.getPerson() != null) {
persons.getPersons().add(dialog.getPerson());
// Updating the display in the view
IWorkbenchPage page = window.getActivePage();
View view = (View) page.findView(View.ID);
view.getViewer().refresh();
}
return null;
}
}
When you finished this successful you are able to add new persons in your application.
We will implement that a person can be deleted from the list after someone selected a person in the table, e.g. via a double click.
Create the command "de.vogella.jface.tableviewer.commands.DeletePerson" with the default handler "de.vogella.jface.tableviewer.commands.DeletePerson". Add the command to your menu.
Implement class "de.vogella.jface.tableviewer.commands.DeletePerson".
package de.vogella.jface.tableviewer.commands;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import de.vogella.jface.tableviewer.View;
import de.vogella.jface.tableviewer.model.ModelProvider;
import de.vogella.jface.tableviewer.model.Person;
public class DeletePerson extends AbstractHandler {
@SuppressWarnings("unchecked")
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
IWorkbenchPage page = window.getActivePage();
View view = (View) page.findView(View.ID);
ISelection selection = view.getSite().getSelectionProvider()
.getSelection();
if (selection != null && selection instanceof IStructuredSelection) {
List<Person> persons = ModelProvider.getInstance().getPersons();
IStructuredSelection sel = (IStructuredSelection) selection;
for (Iterator<Person> iterator = sel.iterator(); iterator.hasNext();) {
Person person = iterator.next();
persons.remove(person);
}
view.getViewer().refresh();
}
return null;
}
}
Please try to delete entries of the table by selection entries and executing "Delete Action".
This chapter shows how to copy the table data to the system clipboard via a command.
Create the command "de.vogella.jface.tableviewer.commands.CopyPersonClipboard" with the default handler "de.vogella.jface.tableviewer.commands.CopyPersonClipboard". Add the command to the menu.
package de.vogella.jface.tableviewer.commands;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import de.vogella.jface.tableviewer.View;
import de.vogella.jface.tableviewer.model.Person;
public class CopyPersonClipboard extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
IWorkbenchPage page = window.getActivePage();
IViewPart view = page.findView(View.ID);
Clipboard cb = new Clipboard(Display.getDefault());
ISelection selection = view.getSite().getSelectionProvider()
.getSelection();
List<Person> personList = new ArrayList<Person>();
if (selection != null && selection instanceof IStructuredSelection) {
IStructuredSelection sel = (IStructuredSelection) selection;
for (Iterator<Person> iterator = sel.iterator(); iterator.hasNext();) {
Person person = iterator.next();
personList.add(person);
}
}
StringBuilder sb = new StringBuilder();
for (Person person : personList) {
sb.append(personToString(person));
}
TextTransfer textTransfer = TextTransfer.getInstance();
cb.setContents(new Object[] { sb.toString() },
new Transfer[] { textTransfer });
return null;
}
private String personToString(Person person) {
return person.getFirstName() + "\t" + person.getLastName() + "\t"
+ person.getGender() + "\t" + person.isMarried()
+ System.getProperty("line.separator");
}
}
Run your application, select a few persons, run your command and paste the result in a text editor, e.g. notepad.
Thank you for practicing with this tutorial.
Please note that I maintain this website in my private time. If you like the information I'm providing please help me by donating.For questions and discussion around this article please use the www.vogella.de Google Group. Also if you note an error in this article please post the error and if possible the correction to the Group.
I believe the following is a very good guideline for asking questions in general and also for the Google group How To Ask Questions The Smart Way.
http://www.vogella.de/articles/EclipseJFaceTable/download/checkedpics.zip The checkbox pictures for the JFace Labelprovider
http://www.vogella.de/code/codeeclipse.html Source Code of Examples
http://www.eclipse.org/articles/Article-Table-viewer/table_viewer.html Building and delivering a table editor with SWT/JFace
http://wiki.eclipse.org/index.php/JFaceSnippets JFace snippets, e.g. small code examples