【问题标题】:Delete rows from Nattable从 Nattable 中删除行
【发布时间】:2015-11-01 15:26:17
【问题描述】:

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

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

我的问题是,最好的方法是:

  • 是否应该在执行this.natview.refresh();时从我的数据模型中删除相应的值并刷新表视图?
  • 我应该从SelectionLayer 获取行并删除它们(如果是,我该怎么做?)?
  • 有没有通过IConfiguration默认支持这个功能?

【问题讨论】:

    标签: swt eclipse-rcp nebula nattable


    【解决方案1】:

    在 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. 将命令处理程序注册到body 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 的命令处理程序并检索所选行,如另一个答案所示。

    【讨论】:

    • 感谢优雅的解决方案。在使用它从数据提供者中删除之前,您不应该将从 command.getRowPosition() 获得的位置转换为索引吗?
    • 这是通过 command.convertToTargetLayer() 在命令处理程序中完成的。由于命令处理程序是主体 DataLayer,因此 index == position
    • 感谢 Dirk 的逐步解释。如我所见,DeleteRowCommand 类的唯一用途是它为命令处理程序提供行位置(尽管可能有更多原因)。那么为什么我们不能只拥有处理程序类。本质上这是一个 Nattable 框架问题
    • 因为命令被触发到层堆栈以触发命令处理程序。它提供了应该删除哪些行的信息。这是 NatTable 中命令的概念,如下所述:vogella.com/tutorials/NatTable/…
    • 我可以对多行​​执行相同的删除吗?
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2016-12-10
      • 2017-04-29
      • 2015-03-14
      • 2015-09-23
      • 1970-01-01
      • 2016-05-25
      • 2015-06-13
      • 2013-03-12
      • 2013-08-12
      相关资源
      最近更新 更多