public class TableEditorTest {
/**
* @param args
*/
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
TableViewer viewer = new TableViewer(shell);
viewer.getTable().setHeaderVisible(true);
viewer.getTable().setLinesVisible(true);
viewer.setContentProvider(new ArrayContentProvider());
TableColumn column = new TableColumn(viewer.getTable(), SWT.NONE);
column.setText("First Name");
column.setWidth(100);
TableViewerColumn firstNameCol = new TableViewerColumn(viewer, column);
firstNameCol.setLabelProvider(new ColumnLabelProvider(){
@Override
public String getText(Object element) {
Person p = (Person)element;
return p.getFirstName();
}
});
column = new TableColumn(viewer.getTable(), SWT.NONE);
column.setText("Last Name");
column.setWidth(100);
TableViewerColumn lastNameCol = new TableViewerColumn(viewer, column);
lastNameCol.setLabelProvider(new ColumnLabelProvider(){
@Override
public String getText(Object element) {
Person p = (Person)element;
return p.getLastName();
}
});
column = new TableColumn(viewer.getTable(), SWT.NONE);
column.setText("Actions");
column.setWidth(100);
TableViewerColumn actionsNameCol = new TableViewerColumn(viewer, column);
actionsNameCol.setLabelProvider(new ColumnLabelProvider(){
//make sure you dispose these buttons when viewer input changes
Map<Object, Button> buttons = new HashMap<Object, Button>();
@Override
public void update(ViewerCell cell) {
TableItem item = (TableItem) cell.getItem();
Button button;
if(buttons.containsKey(cell.getElement()))
{
button = buttons.get(cell.getElement());
}
else
{
button = new Button((Composite) cell.getViewerRow().getControl(),SWT.NONE);
button.setText("Remove");
buttons.put(cell.getElement(), button);
}
TableEditor editor = new TableEditor(item.getParent());
editor.grabHorizontal = true;
editor.grabVertical = true;
editor.setEditor(button , item, cell.getColumnIndex());
editor.layout();
}
});
Person p1 = new Person();
p1.setFirstName("George");
p1.setLastName("Burne");
Person p2 = new Person();
p2.setFirstName("Adam");
p2.setLastName("Silva");
Person p3 = new Person();
p3.setFirstName("Nathan");
p3.setLastName("Cowl");
List<Person> persons = new ArrayList<Person>();
persons.add(p1);
persons.add(p2);
persons.add(p3);
viewer.setInput(persons);
shell.open();
while(!shell.isDisposed())
{
if(!display.readAndDispatch())
{
display.sleep();
}
}
display.dispose();
}
private static class Person
{
String firstName;
String lastName;
Person()
{
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
}
In addition to the answer from @sambi.reddy there is a comment that says - "make sure you dispose these buttons when viewer input changes". This is what I had to do to get that part working.
The framework I used had an implementation of IStructuredContentProvider, so in the overridden inputChanged(...), i had to put in the following code:-
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// This will dispose of all the control button that were created previously
if (((TableViewer)viewer).getTable() != null && ((TableViewer)viewer).getTable().getChildren() != null) {
for (Control item : ((TableViewer)viewer).getTable().getChildren()) {
// at this point there are no other controls embedded in the viewer, however different instances may require more checking of the controls here.
if ((item != null) && (!item.isDisposed())) {
item.dispose();
}
}
}
}
This works fine, except if you have a refresh table (ie. viewer.setInput(List)) call as the result of you button action. When I added this the following line sometimes returned buttons that still existed, but were being disposed:
if(buttons.containsKey(cell.getElement()))
So I needed to update this line to be:
if (buttons.containsKey(cell.getElement()) && !buttons.get(cell.getElement()).isDisposed())
Which resulted in any disposing buttons being recreated, if they were still required.