Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
190 views
in Technique[技术] by (71.8m points)

swt - Delete rows from Nattable

I want to implement a row deletion logic in a Nebula Nattable. This is what I plan to do:

  1. Add context menu to the Nattable which is described in http://blog.vogella.com/2015/02/03/nattable-context-menus-with-eclipse-menus/
  2. 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?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In NatTable you would typically do the following:

  1. 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);
        }
    
    }
    
  2. 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;
        }
    
    }
    
  3. Register the command handler to the body DataLayer

    bodyDataLayer.registerCommandHandler(
            new DeleteRowCommandHandler<your type>(bodyDataProvider.getList()));
    
  4. 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...