Java JTable。删除行。使用事件以不进一步调度

Java JTable。删除行。使用事件以不进一步调度,java,swing,jtable,Java,Swing,Jtable,我需要按delete键从JTable中删除行。所以用例非常简单,用户选择一些行,按delete键,这些行被删除。代码也非常简单: DefaultTableModel tableModel = (DefaultTableModel) table.getModel(); int[] selectedRows = table.getSelectedRows(); for (int i = selectedRows.length - 1; i > -1; i--) {

我需要按delete键从JTable中删除行。所以用例非常简单,用户选择一些行,按delete键,这些行被删除。代码也非常简单:

DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    int[] selectedRows = table.getSelectedRows();
    for (int i = selectedRows.length - 1; i > -1; i--) {
        tableModel.removeRow(selectedRows[i]);
    }
问题是,删除完成后,我们会听到一声“我在windows上”的蜂鸣声,典型的windows蜂鸣声,如在空文本框中按delete键或插入符号位于文本末尾时。 我所做的是,按键被进一步分配到文本组件,该组件显示单元格的文本内容,即删除单元格后的第一个单元格。该蜂鸣音由DefaultEditorKit$DeleteNextCharationActionExecuted方法触发,因为点前面没有字符。 作为黑客,我修改了侦听器中的事件:

e.setKeyCode(KeyEvent.VK_SHIFT) // see JTable#processKeyBinding
事件没有得到进一步的转发,所以嘟嘟声消失了,但我认为这是一个糟糕的解决方案,还有一个更好的解决方案。但哪一个是更好的解决方案

删除行的核心错误,必须从最大索引开始,否则将删除未选中的行, 代码示例

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用户,从未听到Win平台发出的哔哔声,必须发布
请改用键绑定

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,您需要转换到您正在使用的模型

此外,如果您编辑,这可能仍然会触发,因此您需要检查这是否是代码,但我将其修改为一次处理多个选定行,而不是逐个处理:

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

您是否尝试过消费该活动?e、 消费;?是的,这是正确的答案,谢谢这是一个连续的选择每次sry,忘记告诉我,无论如何,消费方法它是正确的答案更改了问题以包含您的删除版本,因为它是更好的没有理由消费任何鼠标或键盘事件,为了获得更好的帮助,请尽快将生成的输出发布到PC的speakereven在您自己的示例中,单击某一行并按delete键,您将听到嘟嘟声