I have a treeviewer with one column containing Strings. I made an "add button".
what I want is when the user add a row, I want to move the "edit cursor" to the new row.
I have 2 problems:
when I add new data with
tableViewer.add()
tableViewer.getTable().getItemCount()
is not updated ! So i can't select the last row...
Plus, when I set ColumnViewerEditorActivationStrategy
. I cannot select anymore with tableViewer.setSelection()
Here the detailled source code
public class CompositeTableViewer extends Composite {
private TableViewer tableViewer;
private List<String> columnNames;
int correctionSelection = 0;
public CompositeTableViewer(Composite parent, int style, List<String> columnNames, boolean rowAddable)
{
this(parent, style, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER, columnNames, rowAddable);
}
public CompositeTableViewer(Composite parent, int style, int tableViewerStyle, List<String> columnNames, boolean rowAddable)
{
super(parent, style);
GridLayout layout = new GridLayout(3, false);
layout.marginWidth = 4;
this.setLayout(layout);
this.setBackground(SWTResourceManager.getColor(SWT.COLOR_DARK_RED));
setTableViewer(new TableViewer(this, tableViewerStyle));
TextCellEditor columnEditor = new TextCellEditor(tableViewer.getTable());
CellEditor[] editors = { columnEditor };
this.columnNames = columnNames;
tableViewer.setColumnProperties(this.columnNames.toArray(new String[this.columnNames.size()]));
tableViewer.setContentProvider(new ArrayContentProvider());
tableViewer.setLabelProvider(new LabelProvider());
tableViewer.setCellEditors(editors);
tableViewer.setCellModifier(new StringListCellModifier(this));
//here I restricted the edit activation to double-click
changeColumnViewerEditorActivationStrategy();
final Table table = tableViewer.getTable();
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
table.setLinesVisible(true);
createButtons(this, rowAddable);
}
public void setInput(List<Object> dataList)
{
this.tableViewer.setInput(dataList);
}
/**
* change the edition activation to double click
* otherwise that's block multi selection :/
*
*/
public TableViewerFocusCellManager changeColumnViewerEditorActivationStrategy()
{
TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer, new FocusCellOwnerDrawHighlighter(tableViewer));
ColumnViewerEditorActivationStrategy activationSupport = new ColumnViewerEditorActivationStrategy(tableViewer)
{
protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event)
{
// Enable editor only with mouse double click
if (event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION)
{
EventObject source = event.sourceEvent;
if (source instanceof MouseEvent && ((MouseEvent) source).button == 3)
return false;
return true;
}
return false;
}
};
TableViewerEditor.create(tableViewer, focusCellManager, activationSupport, ColumnViewerEditor.TABBING_HORIZONTAL
| ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION);
return focusCellManager;
}
/**
* Add the "Add" and "Delete" buttons
*
* @param parent
* the parent composite
*/
private void createButtons(Composite parent, boolean rowAddable)
{
// Create and configure the "Add" button
Button add = new Button(parent, SWT.PUSH | SWT.CENTER);
add.setText("Add");
GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gridData.widthHint = 80;
add.setLayoutData(gridData);
add.setEnabled(rowAddable);
add.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
tableViewer.add("-_-"); // suppose to be an empty string
int selection = CompositeTableViewer.this.tableViewer.getTable().getItemCount();
CompositeTableViewer.this.tableViewer.setSelection(
new StructuredSelection(tableViewer.getElementAt(selection - 1 + correctionSelection)), true);
tableViewer.setSelection(new StructuredSelection(CompositeTableViewer.this.tableViewer.getElementAt(selection - 1)), true);
}
});
// Create and configure the "Delete" button
Button delete = new Button(parent, SWT.PUSH | SWT.CENTER);
delete.setText("Delete");
gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gridData.widthHint = 80;
delete.setLayoutData(gridData);
delete.addSelectionListener(new SelectionAdapter()
{
// Remove the selection and refresh the view
public void widgetSelected(SelectionEvent e)
{
Object[] dataTable = (Object[]) ((IStructuredSelection) tableViewer.getSelection()).toArray();
if (dataTable != null)
{
tableViewer.remove(dataTable);
}
}
});
}
}
EDIT The problem was ArraycontentProvider can't be used for an editable table. and I should not use a list as a model. I change for a List. I put in comment my new source code
I imported your code and modified it a little bit, and there's some things that seems to be wrong from what I can see.
First, ArraycontentProvider says this in the java doc:
this implementation of IStructuredContentProvider handles the case where the viewer input is an unchanging array or collection of elements
So your first task would be to write your own content provider. This is important because you will need to update the input you've set, and this content provider will likely not do that for you.
Second, you need to add columns to make them editable. For example:
TableViewerColumn c1 = new TableViewerColumn(tableViewer, tableViewerStyle);
c1.setLabelProvider(new CellLabelProvider() {
@Override
public void update(ViewerCell cell) {
}
});
c1.getColumn().setWidth(200);
c1.setEditingSupport(new FirstNameEditingSupport(tableViewer));
This will make your column editable with a dedicated editor. (Text in that case. I stole the editor from a nice tutorial that you can find here:
http://www.vogella.com/tutorials/EclipseJFaceTableAdvanced/article.html#jfaceeditor
Now with these changes, I managed to solve your problem of adding. You will need to have a model object that you can update. In my case, I created:
public static class TestObject {
private String text;
public TestObject(String text) {
this.text = text;
}
}
This is needed because in the editor, you will have to update the viewer's content with the edited content.
What I didn't do was to create a proper ContentProvider, so in my example I never persist my updates. However, the adding works, the double click works, and the editing works.
Now to your selection. The tableviewer add method says:
This method should be called (by the content provider) when a single element has been added to the model, in order to cause the viewer to accurately reflect the model. This method only affects the viewer, not the model. Note that there is another method for efficiently processing the simultaneous addition of multiple elements.
This comes back to your content provider. It needs to handle the fact that content has been added/edited/removed and update the model object accordingly.
This should get you started for now. Have a look at the tutorial by Lars vogel, it is very good and clear what to do. Let me know if there's more issues and i'll attempt to create a better example.
Artur
P.S.: Copy/pasting your code did not compile for me. Try providing a mini standalone example for your problem. That way it's easier to code against it and give you more detailed pointers.