I want to implement a row deletion logic in a Nebula Nattable. This is what I plan to do:
- Add context menu to the Nattable which is described in http://blog.vogella.com/2015/02/03/nattable-context-menus-with-eclipse-menus/
- Add an SWT Action to the menu which will implement the delete
my question is, which is the best way to accomplish this:
- Should I delete the corresponding value from my data model and the table view is refreshed when I execute
this.natview.refresh();
? OR - Should I get the rows from
SelectionLayer
and delete them (if so how do I do ?)? OR - is there any default support for this function through
IConfiguration
?
In NatTable you would typically do the following:
Create a command for deleting a row
public class DeleteRowCommand extends AbstractRowCommand { public DeleteRowCommand(ILayer layer, int rowPosition) { super(layer, rowPosition); } protected DeleteRowCommand(DeleteRowCommand command) { super(command); } @Override public ILayerCommand cloneCommand() { return new DeleteRowCommand(this); } }
Create a command handler for that command
public class DeleteRowCommandHandler<T> implements ILayerCommandHandler<DeleteRowCommand> { private List<T> bodyData; public DeleteRowCommandHandler(List<T> bodyData) { this.bodyData = bodyData; } @Override public Class<DeleteRowCommand> getCommandClass() { return DeleteRowCommand.class; } @Override public boolean doCommand(ILayer targetLayer, DeleteRowCommand command) { //convert the transported position to the target layer if (command.convertToTargetLayer(targetLayer)) { //remove the element this.bodyData.remove(command.getRowPosition()); //fire the event to refresh targetLayer.fireLayerEvent(new RowDeleteEvent(targetLayer, command.getRowPosition())); return true; } return false; } }
Register the command handler to the body DataLayer
bodyDataLayer.registerCommandHandler( new DeleteRowCommandHandler<your type>(bodyDataProvider.getList()));
Add a menu item to your menu configuration that fires the command
new PopupMenuBuilder(natTable) .withMenuItemProvider(new IMenuItemProvider() { @Override public void addMenuItem(NatTable natTable, Menu popupMenu) { MenuItem deleteRow = new MenuItem(popupMenu, SWT.PUSH); deleteRow.setText("Delete"); deleteRow.setEnabled(true); deleteRow.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { int rowPosition = MenuItemProviders.getNatEventData(event).getRowPosition(); natTable.doCommand(new DeleteRowCommand(natTable, rowPosition)); } }); } }) .build();
Using this you don't need to call NatTable#refresh()
because the command handler fires a RowDeleteEvent
. I also don't suggest to call NatTable#refresh()
in such a case, as it might change and refresh more than it should and would not update other states correctly, which is done correctly by firing the RowDeleteEvent
.
Note that the shown example deletes the row for which the context menu is opened. If all selected rows should be deleted, you should create a command handler that knows the SelectionLayer
and retrieve the selected rows as shown in the other answer.
In our application we do the following:
Get selected row objects:
SelectionLayer selectionLayer = body.getSelectionLayer(); int[] selectedRowPositions = selectionLayer.getFullySelectedRowPositions(); Vector<Your Model Objects> rowObjectsToRemove = new Vector<Your Model Objects>(); for (int rowPosition : selectedRowPositions) { int rowIndex = selectionLayer.getRowIndexByPosition(rowPosition); rowObjectsToRemove .add(listDataProvider.getRowObject(rowIndex)); }
Remove them from the data provider
- call
natTable.refresh()
来源:https://stackoverflow.com/questions/31907288/delete-rows-from-nattable