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

时间:2012-09-04 11:52:31

标签: java swing 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

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

3 个答案:

答案 0 :(得分:4)

  • 删除行的核心是错误的,必须从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

答案 1 :(得分: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,你需要使用你正在使用的模型。

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

答案 2 :(得分:0)

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

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