如何使 JTable 单元格中的 JButton 可点击? [英] How to make a JButton in a JTable cell click-able?

查看:43
本文介绍了如何使 JTable 单元格中的 JButton 可点击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有自定义单元格渲染器的 JTable.该单元格是一个 JPanel,其中包含一个 JTextField 和一个 JButton.JTextField 包含一个整数,当用户点击 JButton 时,该整数应该增加.

I have a JTable with a custom cell renderer. The cell is a JPanel that contains a JTextField and a JButton. The JTextField contains an integer, and when the user clicks on the JButton the integer should be increased.

问题是当我在 JTable 单元格中有 JButton 时无法单击它.我怎样才能让它可以点击?

The problem is that the JButton can't be clicked when I have it in a JTable cell. How can I make it click-able?

这是我的测试代码:

public class ActiveTable extends JFrame {

    public ActiveTable() {
        RecordModel model = new RecordModel();
        model.addRecord(new Record());
        JTable table = new JTable(model);
        EditorAndRenderer editorAndRenderer = new EditorAndRenderer();
        table.setDefaultRenderer(Object.class, editorAndRenderer);
        table.setDefaultEditor(Object.class, editorAndRenderer);
        table.setRowHeight(38);

        add(new JScrollPane(table));
        setPreferredSize(new Dimension(600, 400));
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setTitle("Active Table");
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ActiveTable();
            }
        });
    }

    class RecordModel extends AbstractTableModel {

        private final List<Record> records = new ArrayList<Record>();

        @Override
        public int getColumnCount() {
            return 1;
        }

        @Override
        public int getRowCount() {
            return records.size();
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return records.get(rowIndex);
        }

        public void addRecord(Record r) {
            records.add(r);
            fireTableRowsInserted(records.size()-1, records.size()-1);
        }

    }

    class Record {
        private int count = 1;
        public int getCount() { return count; }
        public void increase() { count = count + 1; }
    }

    class CellPanel extends JPanel {
        private Record record;
        private final JTextField field = new JTextField(8);
        private final Action increaseAction = new AbstractAction("+") {
            public void actionPerformed(ActionEvent e) {
                record.increase();
                field.setText(record.getCount()+"");
                JTable table = (JTable) SwingUtilities.getAncestorOfClass(JTable.class, (Component) e.getSource());
                table.getCellEditor().stopCellEditing();
            }
        };
        private final JButton button = new JButton(increaseAction);

        public CellPanel() {
            add(field);
            add(button);
        }

        public void setRecord(Record r) {
            record = r;
            field.setText(record.getCount()+"");
        }

        public Record getRecord() {
            return record;
        }
    }

    class EditorAndRenderer extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {

        private final CellPanel renderer = new CellPanel();
        private final CellPanel editor = new CellPanel();

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column) {
            renderer.setRecord((Record) value);
            return renderer;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value,
                boolean isSelected, int row, int column) {
            editor.setRecord((Record) value);
            return editor;
        }

        @Override
        public Object getCellEditorValue() {
            return editor.getRecord();
        }

        @Override
        public boolean isCellEditable(EventObject ev) {
            return true;
        }

        @Override
        public boolean shouldSelectCell(EventObject ev) {
            return false;
        }
    }
}

推荐答案

我的最后一个示例基于 mKrobels 对 的回答提供的代码如何在swing中实现动态GUI

I based my last example on the code provided by mKrobels answer to How to implement dynamic GUI in swing

他和我在问题中的示例之间的主要区别在于他使用 DefaultTableModel 而我使用 AbstractTableModel.他的例子确实有效,但我的无效.

The main difference between his and my example in the question is that he use DefaultTableModel and I use AbstractTableModel. His example does work, but not mine.

我找到的解决方案是我必须在 TableModel 中实现 isCellEditable(),所以添加了这个方法,我的例子就可以工作了:

The solution I found was that I had to implement isCellEditable() in the TableModel, so with this method added, my example works:

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
    return true;
}

这篇关于如何使 JTable 单元格中的 JButton 可点击?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆