【问题标题】:Delete Multiple rows from Nattable从 Nattable 中删除多行
【发布时间】:2016-12-10 10:33:50
【问题描述】:

我正在尝试从NatTable 中删除不止一行。遵循Delete rows from Nattable 中描述的解决方案。我创建了以下类: Command 类如下所示:

public class DeleteMultiRowCommand extends AbstractMultiRowCommand {

    public DeleteMultiRowCommand(AbstractMultiRowCommand command) {
        super(command);
    }

    protected DeleteMultiRowCommand(ILayer layer, int[] rowPositions) {
        super(layer, rowPositions);
    }

    @Override
    public ILayerCommand cloneCommand() {
        return new DeleteMultiRowCommand(this);
    }

}

命令处理程序类:

public class DeleteMultiRowCommandHandler<T> implements ILayerCommandHandler<DeleteMultiRowCommand> {

    private List<T> bodyData;
    private SelectionLayer layer;

    public DeleteMultiRowCommandHandler(List<T> bodyData, SelectionLayer selectionLayer) {
        this.bodyData = bodyData;
        this.layer = selectionLayer;
    }

    public DeleteMultiRowCommandHandler(List<T> bodyData){
        this.bodyData = bodyData;
    }

    @Override
    public Class<DeleteMultiRowCommand> getCommandClass() {
        return DeleteMultiRowCommand.class;
    }

    @Override
    public boolean doCommand(ILayer targetLayer, DeleteMultiRowCommand command) {
        //convert the transported position to the target layer
        if (command.convertToTargetLayer(targetLayer)) {
            Collection<Integer>rowpos = command.getRowPositions();
            //remove the element
            for(Integer val : rowpos){
                this.bodyData.remove(val.intValue());
                targetLayer.fireLayerEvent(new RowDeleteEvent(targetLayer, val.intValue()));
            }

            return true;
        }
        return false;
    }

}

并且命令将在单击 MenuItem 时触发

this.contextMenu = new PopupMenuBuilder(natTable)
            .withInspectLabelsMenuItem()
            .withClearAllFilters()
            .withColumnRenameDialog()
            .withMenuItemProvider(new IMenuItemProvider() {

                @Override
                public void addMenuItem(final NatTable natTable, Menu popupMenu) {
                    MenuItem deleteRow = new MenuItem(popupMenu, SWT.PUSH);
                    deleteRow.setText("Delete Row(s)");
                    deleteRow.setEnabled(true);

                    deleteRow.addSelectionListener(new SelectionAdapter() { 
                        @Override
                        public void widgetSelected(SelectionEvent event) {
                            //int rowPosition = MenuItemProviders.getNatEventData(event).getRowPosition();
                            ILayer bl = ((GridLayer)natTable.getLayer()).getBodyLayer();
                            BodyLayerStack bl1 = (BodyLayerStack) bl;
                            SelectionLayer sl = bl1.getSelectionLayer();
                            int []poss = new int[sl.getFullySelectedRowPositions().length];
                            int i=0;
                            for(int pos1 : sl.getFullySelectedRowPositions()){
                                poss[i]=sl.getRowIndexByPosition(pos1);
                                i++;
                            }
                            //System.out.println("Menu item selected "+rowPosition);
                            //natTable.doCommand(new DeleteRowCommand(natTable, rowPosition));
                            natTable.doCommand(new DeleteMultiRowCommand(natTable, poss));
                        }
                    });
                }
            })
            .build();

当我尝试删除行时,未选择的行将被删除。似乎是行位置到行索引转换的问题。我的IMenuItemProvider 中的行位置到行索引转换是否正确?

【问题讨论】:

    标签: eclipse-rcp nattable nebula


    【解决方案1】:

    您似乎做了两次从位置到索引的转换:一次在菜单项选择侦听器中,一次在命令处理程序中(通过调用convertToTargetLayer)。第一个不是必需的。

    【讨论】:

    • 以前我没有使用getRowIndexByPosition,但这导致了删除其他行的相同问题。
    【解决方案2】:

    这不是 NatTable 的问题,而是关于如何使用集合的问题。如果您逐个删除元素,则需要向后删除项目。否则,索引的项目在处理时会发生变化。

    假设您要删除索引 1 和 2 处的元素。删除索引 1 处的元素后,下面的元素将向上移动。因此,之前在索引 2 上的元素现在将在索引 1 上,而在索引 3 处的元素将在索引 2 上。因此,在下一次迭代中删除索引 2 处的元素将删除之前在索引上的项目3.

    我建议在迭代从集合中删除项目之前对索引集合进行排序和反转。比它应该工作。

    【讨论】:

    • 我更改了我的 Commandhandler doCommand 方法,将选定的对象存储在一个临时的 ArrayList 中,然后通过 ArrayList.remove(Object) 方法删除。但问题仍然存在。我也有一个过滤器行。我还注意到,如果我尝试删除第一行,command.convertToTargetLayer(targetLayer) 方法会返回 false。
    • 如果该方法仍然存在问题,则您在错误的列表中操作。我想该表显示了 FilterList 的内容,但您正在对基本列表进行操作。您应该检查您是否在同一个列表实例上进行操作。
    • 这就是我创建 CommandHandler 的方式:List data = ((ListDataProvider)bodyLayerStack.getBodyDataProvider()).getList(); bodyLayerStack.getBodyDataLayer().registerCommandHandler(new DeleteRowCommandHandler(data,bodyLayerStack.getSelectionLayer())); bodyLayerStack.getBodyDataLayer().registerCommandHandler(new DeleteMultiRowCommandHandler(data)); 我正在使用 FilterList 来创建 BodyDataProvider
    • 抱歉,我无法远程调试您的代码。关于收藏,你的作文有些不对劲。您需要调试并检查集合及其内容与您要删除的内容相比。
    • 如果我不使用getRowIndexByPosition,(如@Arye Shemesh 所建议的那样),删除似乎适用于除第一行和第二行之外的所有行。现在命令看起来像这样natTable.doCommand(new DeleteMultiRowCommand(natTable, sl.getFullySelectedRowPositions()));。仍然需要弄清楚为什么不能删除第一行和第二行。
    猜你喜欢
    • 2015-11-01
    • 2017-04-29
    • 2015-09-23
    • 2015-03-14
    • 2016-09-21
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多