2

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

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

问题是删除完成后,我们会听到一声哔声(我在 windows 上,典型的 windows 哔声),就像在空文本框中按下删除键时(或者当插入符号位于末尾时)文本)。我正在发生的事情是按键被进一步发送到显示单元格文本内容的文本组件(已删除单元格之后的第一个单元格)。哔声由 DefaultEditorKit$DeleteNextCharAction#actionPerformed 方法触发,因为点前面没有字符。作为 hack,我修改了侦听​​器中的事件:

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

该事件没有进一步转发,因此哔哔声消失了,但我认为这是一个糟糕的解决方案,并且有一个更好的解决方案。但哪个是更​​好的解决方案?

4

3 回答 3

4
  • 你删除行的核心是错误的,必须从最大索引开始,否则删除未选中的行,

代码示例

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 平台的哔哔声,必须发布SSCCE
于 2012-09-04T12:15:21.393 回答
1

改用键绑定...

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

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

于 2012-09-04T20:19:26.580 回答
0

这是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);
            }
        }
    });
于 2014-06-26T21:00:42.003 回答