JTable中。 删除行。 消耗事件不要进一步调度

我需要在删除按键上删除JTable中的行。 所以用例很简单,用户选择一些行,按删除键,行被删除。 代码也很简单:

DefaultTableModel tableModel = (DefaultTableModel) table.getModel(); int[] selectedRows = table.getSelectedRows(); for (int i = selectedRows.length - 1; i > -1; i--) { tableModel.removeRow(selectedRows[i]); } 

问题是,删除完成后,我们会听到一声蜂鸣声(我在窗户上,典型的窗口发出蜂鸣声),就像在空文本框中按下删除键一样(或当插入符号位于末尾时)文本)。 我正在发生的事情是按键被进一步发送到文本组件,该文本组件显示单元格的文本内容(删除后的第一个单元格)。 默认情况下,DefaultEditorKit $ DeleteNextCharAction#actionPerformed方法触发蜂鸣声,因为点前面没有字符。 作为一个黑客,我在监听器中修改事件:

 e.setKeyCode(KeyEvent.VK_SHIFT) // see JTable#processKeyBinding 

事件没有进一步转发,所以蜂鸣声消失,但我认为这是一个糟糕的解决方案,而且还有一个更好的解决方案。 但哪个是更​​好的解决方案?

使用键绑定代替……

 InputMap im = table.getInputMap(JTable.WHEN_FOCUSED); ActionMap am = table.getActionMap(); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "DeleteRow"); am.put("DeleteRow", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Delete row"); int row = table.getSelectedRow(); if (row > -1) { DefaultTableModel model = (DefaultTableModel) table.getModel(); model.removeRow(row); } } }); 

(我为测试借用了mKorbel数据,因此我的测试使用的是DefaultTableModel ,您需要转换为您正在使用的模型)。

此外,如果您进行编辑,这可能仍会触发,因此您需要检查该内容

  • 你删除行的核心是错误的,必须从Max索引开始,否则删除未选择的行,

代码示例

 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.table.*; public class RemoveAddRows extends JFrame { private static final long serialVersionUID = 1L; private Object[] columnNames = {"Type", "Company", "Shares", "Price"}; private Object[][] data = { {"Buy", "IBM", new Integer(1000), new Double(80.50)}, {"Sell", "MicroSoft", new Integer(2000), new Double(6.25)}, {"Sell", "Apple", new Integer(3000), new Double(7.35)}, {"Buy", "Nortel", new Integer(4000), new Double(20.00)}, {"Buy", "IBM", new Integer(1000), new Double(80.50)}, {"Sell", "MicroSoft", new Integer(2000), new Double(6.25)}, {"Sell", "Apple", new Integer(3000), new Double(7.35)}, {"Buy", "Nortel", new Integer(4000), new Double(20.00)}, {"Buy", "IBM", new Integer(1000), new Double(80.50)}, {"Sell", "MicroSoft", new Integer(2000), new Double(6.25)}, {"Sell", "Apple", new Integer(3000), new Double(7.35)}, {"Buy", "Nortel", new Integer(4000), new Double(20.00)} }; private JTable table; private DefaultTableModel model; public RemoveAddRows() { model = new DefaultTableModel(data, columnNames) { private static final long serialVersionUID = 1L; @Override public Class getColumnClass(int column) { return getValueAt(0, column).getClass(); } }; table = new JTable(model); table.setPreferredScrollableViewportSize(table.getPreferredSize()); table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); JScrollPane scrollPane = new JScrollPane(table); add(scrollPane); JButton button1 = new JButton("Remove all rows"); button1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { int[] selectedRows = table.getSelectedRows(); for (int i = selectedRows.length - 1; i > -1; i--) { model.removeRow(selectedRows[i]); } /*if (model.getRowCount() > 0) { for (int i = model.getRowCount() - 1; i > -1; i--) { model.removeRow(i); } }*/ System.out.println("model.getRowCount() --->" + model.getRowCount()); } }); JButton button2 = new JButton("Add new rows"); button2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { Object[] data0 = {"Buy", "IBM", new Integer(1000), new Double(80.50)}; model.addRow(data0); Object[] data1 = {"Sell", "MicroSoft", new Integer(2000), new Double(6.25)}; model.addRow(data1); Object[] data2 = {"Sell", "Apple", new Integer(3000), new Double(7.35)}; model.addRow(data2); Object[] data3 = {"Buy", "Nortel", new Integer(4000), new Double(20.00)}; model.addRow(data3); System.out.println("model.getRowCount() --->" + model.getRowCount()); } }); JPanel southPanel = new JPanel(); southPanel.add(button1); southPanel.add(button2); add(southPanel, BorderLayout.SOUTH); } public static void main(String[] args) { RemoveAddRows frame = new RemoveAddRows(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } } 
  • 我赢了用户并且从未听过Win Platform的哔声,必须发布一个SSCCE

这是MadProgrammer的代码,但我修改它以同时处理多个选定的行而不是一个一个:

  // Assume table is a JTable instance InputMap inputMap = table.getInputMap(JTable.WHEN_FOCUSED); ActionMap actionMap = table.getActionMap(); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "DeleteRow"); actionMap.put("DeleteRow", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { int[] row = table.getSelectedRows(); for (int i = 0; i < row.length; i++) { ((DefaultTableModel) table.getModel()).removeRow(row[i] - i * 1); } } });