Tips on developing Eclipse plugins – IV.

In today’s article I am going to describe a bunch more useful techniques for JFace which might be used in Eclipse Plugin Development as well. It will be:

  • How to get the index of selected column in TableViewer
  • How to create and use TreeViewer with multiple equal items

Getting the index of selected column in TableViewer

Let’s say we want do some action when user double clicks on the row in TableViewer. Achieving this is easy, the code might look like this:

[java]
tableViewer.addDoubleClickListener(new IDoubleClickListener(){
public void doubleClick(DoubleClickEvent event) {
Object selectedItem = ((StructuredSelection)event.getSelection())
.getFirstElement();
//process selectedItem which is our row item as provided
//by our IStructuredContentProvider
}
}
[/java]

If we need to know not only which row but also which exact column was double clicked, things get more complicated then that because there doesn’t seem to be direct standard support for this:

[java]
tableViewer.addDoubleClickListener(new IDoubleClickListener(){
public void doubleClick(DoubleClickEvent event) {
int selectedColumn = -1;

Table tab = ((TableViewer)event.getViewer()).getTable();
Point pt = tab.toControl(Display.getCurrent().getCursorLocation());

for (int i = 0; i < table.getColumnCount(); i++) { TableItem item = table.getItem(pt); if (item != null) { if (item.getBounds(i).contains(pt)) { selectedColumn = i; } } } Object selectedItem = ((StructuredSelection)event.getSelection()). getFirstElement(); //process selectedItem which is our row item as provided //by our IStructuredContentProvider, selectedColumn //is the index of column (or -1 if there was problem) } } [/java]

Creating TreeViewer with multiple equal items

There are situations where we want a TreeViewer to contain multiple items that are equal (i.e. X.equals(Y) returns true for items X, Y).

An example of such situation would be tree containing classes (as root nodes) with every class having its super class as a child node. Then it is possible to imagine having class A as a root node and class B as its child node (which means class A extends class B) – but class B might be also root node (with another class C as a child).

We can see that class B is contained twice in the TreeViewer and this may lead to problems (one of which is incorrectly working treeViewer.setSelection(B) – it will randomly select one of two B class nodes depending on circumstances).

The solution consists of these steps:

  1. Use ITreePathContentProvider instead of commonly used ITreeContentProvider content provider
  2. Before selecting the item in tree do treeViewer. setSelection(null) first – this is needed to get around what I am not sure is feature or bug 😉 – there is some internal hash table used and if currently selected item has the same hashCode() as the new one, the new selection is ignored. Setting null before real selection helps.
  3. For selecting item in tree use setSelection(treePath) (instead of setSelection(item)) – simply put, TreePath is path consisting of items from root to item we want to select (inclusive)

Tags: , , , , ,

Comments are closed.