2011-10-26 132 views
0

我想爲JTable提供多單元格編輯功能:雙擊仍然會編輯所選單元格中的值(標準行爲),而右鍵單擊應打開一個彈出菜單中的條目「編輯選定的單元格」。Swing中的多單元格選擇JTable

當用戶點擊此菜單項時,所選範圍中的最後一個單元格變爲可編輯。其他選中的單元格保持選中狀態然後他們寫入新值,並在版本完成後(通常按Enter),所有選定的單元格都會獲得該值。

爲簡單起見,我們假設所有單元格都包含相同的值類型,例如整數。

下面是顯示了彈出對話框的代碼,上手:

table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); 
table.setCellSelectionEnabled(true); 
table.addMouseListener(new MouseAdapter() { 
    @Override 
    public void mousePressed(MouseEvent e) { 
     if (e.isPopupTrigger()) { 
      doPop(e); 
     } 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     if (e.isPopupTrigger()) { 
      doPop(e); 
     } 
    } 

    private void doPop(MouseEvent e) { 
     MultiEditPopUp menu = new MultiEditPopUp(tblRanges); 
     menu.show(e.getComponent(), e.getX(), e.getY()); 
    } 
}); 


class MultiEditPopUp extends JPopupMenu { 
    JMenuItem menuItem; 

    MultiEditPopUp(JTable table) { 
     menuItem = new JMenuItem("Edit selected"); 
     menuItem.setAction(new BulkEditAction(table)); 
     add(menuItem); 
    } 
} 

class BulkEditAction extends AbstractAction { 
    private final JTable table; 

    public BulkEditAction(JTable table) { 
     this.table = table; 
    } 

    @Override 
    public void actionPerformed(ActionEvent actionEvent) { 
     // TODO: let the user edit the last cell, and then apply to the others 
    } 
} 

我怎樣才能做這樣的事情?

+0

究竟是什麼問題?當接收到編輯後的值時,將它傳播給所有選中的單元格,並且很高興:-) – kleopatra

+1

幾個註釋(與我沒有得到的問題無關;-) a)不分類任何JSomething,而是使用它們(JPopupMenu被設計爲添加動作/項目,不需要爲了添加特定項目而繼承子類)b)始終使用最高抽象,這裏意味着setComponentPopupMenu而不是mouseListener(它提供了不完整的功能,無論如何,通過鍵盤覆蓋彈出窗口) – kleopatra

+0

現在的問題是如何讓用戶編輯該單元格,同時保留選擇內容。 感謝您對子類的建議。 – espinchi

回答

2

仍然不太確定問題所在。其基本做法是

  • 店選定單元格
  • 讓用戶編輯其中的一個
  • 末,以編輯值,並將其設置爲以前存儲

所有單元格我看到的唯一棘手的部分可能是「最終」檢測(因爲編輯的生命週期不是很好定義)。一些代碼片段

public class BulkEditAction extends AbstractAction { 
    JTable table; 
    List selectedCells; 

    public BulkEditAction(JTable table) { 
     this.table = table; 
    } 

    @Override 
    public void actionPerformed(ActionEvent actionEvent) { 

     // store, here rows only, refine for cell selection 
     selectedCells = Arrays.asList(table.getSelectedRows()); 
     final int rowToEdit = // ... 
     final int columnToEdit = // ... 
     table.editCellAt(rowToEdit, columnToEdit); 
     CellEditorListener l = new CellEditorListener() { 

      @Override 
      public void editingStopped(ChangeEvent e) { 
       ((AbstractCellEditor) e.getSource()).removeCellEditorListener(this); 
       propagateEditedValue(rowToEdit, columnToEdit); 

      } 

      @Override 
      public void editingCanceled(ChangeEvent e) { 
       ((AbstractCellEditor) e.getSource()).removeCellEditorListener(this); 
      } 
     }; 
     table.getCellEditor().addCellEditorListener(l); 
    } 

    private void propagateEditedValue(final int row, final int column) { 
     // need to invoke to be sure that the table has updated itself after 
     // editingStopped 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       // foreach selectedCell (with coordinates selectedRow/-column 
       table.setValueAt(table.getValueAt(row, column), selectedRow, selectedColumn); 
      } 
     }); 
    } 
} 
+0

非常好的解決方案,這就像一個魅力。 我在嘗試解決用戶體驗問題:當您編輯該單元格時,「全選」不起作用,更糟糕的是,如果您點擊一個箭頭,則光標將移動,批量版本將被執行。如果我管理,我會回覆補充此答案。 任何想法? – espinchi