2016-08-04 10 views
0

Я пытаюсь удалить более одной строки из NatTable. Следуя решению, описанному в Delete rows from Nattable. Я создал следующие классы: класс команд выглядит следующим образом:Удалить несколько строк из 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); 
    } 

} 

Command Handler Класс:

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

, когда я пытаюсь удалить строки, удаленные строки не удаляются. Похоже, проблема с позицией строки для преобразования индекса строки. Является ли строка postion преобразованием индекса строки правильным в пределах моего IMenuItemProvider?

ответ

1

Кажется, что вы делаете преобразование из положения в индекс дважды: один раз в приемнике выбора пункта меню и один раз в обработчике команд (путем вызова convertToTargetLayer). Первое не обязательно.

+0

ранее я не использовал 'getRowIndexByPosition', но это вызывало ту же проблему с удалением некоторой другой строки. – ssdimmanuel

1

Это не проблема NatTable, а вопрос о том, как работать с коллекциями. Вам нужно удалить элементы назад, если вы удалите элементы по одному. В противном случае элементы для индексов изменяются во время обработки.

Предположим, вы хотите удалить элементы в индексах 1 и 2. После удаления элемента с индексом 1 элементы ниже будут перемещаться вверх. Таким образом, элемент, который раньше был на индексе 2, теперь будет на индексе 1, а элемент в индексе 3 будет на индексе 2. Поэтому удаление элемента по индексу 2 в следующей итерации приведет к удалению элемента, который был ранее по индексу 3.

Я бы предложил отсортировать и отменить сбор индексов перед повторением, чтобы удалить элементы из коллекции. Чем это должно сработать.

+0

Я изменил метод Commandhandler, как показано ниже. – ssdimmanuel

+0

Я изменил метод CommandCommand 'Command', чтобы сохранить выбранные объекты во временном' ArrayList', а затем удалить методом 'ArrayList.remove (Object)'. Но проблема все же сохраняется. У меня также есть строка Filter. Я также мог заметить, что метод 'command.convertToTargetLayer (targetLayer)' возвращает false, если я пытаюсь удалить первую строку. – ssdimmanuel

+0

Если проблема по-прежнему присутствует в этом подходе, вы работаете с неправильным списком. Я полагаю, что таблица показывает содержимое FilterList, но вы работаете в базовом списке. Вы должны проверить, что вы работаете с одним экземпляром списка. –