2011-10-26 118 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