从 Nattable 中删除行

Delete rows from Nattable

我想在 Nebula Nattable 中实现行删除逻辑。 这就是我打算做的:

  1. http://blog.vogella.com/2015/02/03/nattable-context-menus-with-eclipse-menus/
  2. 中描述的 Nattable 添加上下文菜单
  3. 将 SWT 操作添加到将实现删除的菜单

我的问题是,这是完成此任务的最佳方法:

在我们的应用程序中,我们执行以下操作:

  1. 获取选定的行对象:

    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));
    }
    
  2. 从数据提供者中删除它们

  3. 致电natTable.refresh()

在 NatTable 中,您通常会执行以下操作:

  1. 创建删除行的命令

    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. 为该命令创建命令处理程序

    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. 将命令处理程序注册到主体 DataLayer

    bodyDataLayer.registerCommandHandler(
            new DeleteRowCommandHandler<your type>(bodyDataProvider.getList()));
    
  4. 向您的菜单配置添加一个菜单项以触发命令

    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();
    

使用这个你不需要调用 NatTable#refresh() 因为命令处理程序会触发 RowDeleteEvent。我也不建议在这种情况下调用 NatTable#refresh(),因为它可能会比应有的更改和刷新更多,并且不会正确更新其他状态,这是通过触发 RowDeleteEvent 正确完成的。

请注意,所示示例删除了为其打开上下文菜单的行。如果应删除所有 selected 行,您应该创建一个知道 SelectionLayer 的命令处理程序并检索所选行,如其他答案所示。