2016-08-04 125 views
0

我想從NatTable刪除多行。遵循Delete rows from Nattable中描述的解決方案。我創建了以下類: Command類看起來是這樣的:從Nattable中刪除多行

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; 
    } 

} 

,並命令將在點擊菜單項

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正確的行索引轉換正確嗎?

回答

1

看起來像你做了兩次從位置到索引的轉換:一次在菜單項選擇偵聽器中,一次在命令處理程序中(通過調用convertToTargetLayer)。第一個沒有必要。

+0

以前我沒有使用'getRowIndexByPosition',但這導致刪除其他行的相同問題。 – ssdimmanuel

1

這不是NatTable的問題,而是關於如何使用集合的問題。如果逐個刪除元素,則需要將項目向後移除。否則,索引的項目在處理時會發生變化。

假設您想要刪除索引1和2中的元素。刪除索引1處的元素後,下面的元素將向上移動。因此,索引2之前的元素現在位於索引1上,索引3中的元素位於索引2上。因此,在下一次迭代中刪除索引2處的元素將刪除索引之前的項目3.

我建議在迭代刪除集合中的項目之前對索引集合進行排序和反轉。比它應該工作。

+0

我改變了我的Commandhandler方法,如下所示 – ssdimmanuel

+0

我改變了我的Commandhandler'doCommand'方法,將選定的對象存儲在一個臨時的'ArrayList'中,然後通過'ArrayList.remove(Object)'方法刪除。但問題仍然存在。我也有一個Filter行。我還可以注意到,如果我嘗試刪除第一行,則'command.convertToTargetLayer(targetLayer)'方法返回false。 – ssdimmanuel

+0

如果問題仍然存在,您正在使用錯誤列表。我想表格顯示了FilterList的內容,但是你正在基本列表上進行操作。你應該檢查你是否在同一個列表實例上運行。 –