java - 在 JButton 上执行 actionPerformed,因为 TableCellEditor 在 MouseDown 上错误地调用

标签 java swing jbutton actionlistener tablecelleditor

我正在尝试将 JButton 用作 JTableTableCellRendererTableCellEditor。在我的测试场景中,我有 5 行,每行显示一个 JButton 作为渲染器和编辑器(编辑器和渲染器的不同按钮实例)。当我第一次单击一个按钮时,当我释放鼠标按钮时,将调用编辑器按钮的 actionPerformed 。当我单击另一行中的另一个按钮时,当我按下鼠标按钮(MOUSE_PRESSED)时,编辑器按钮的 actionPerformed 事件已经被调用。这种行为看起来不太对劲。通常,actionPerformed 事件在释放鼠标按钮时调用,而不是在按下鼠标按钮时调用。当随后按下另一行中的另一个按钮时,在释放鼠标按钮时再次正确调用 actionPerformed ,在下一个按钮上单击另一行中的 actionPerformed 再次(错误地)调用MOUSE_DOWN 等等。

将焦点移出表格然后单击按钮时,释放鼠标按钮时会正确调用 actionPerformed。此外,当要单击的按钮所在的行中的表行编辑器首先获得焦点(激活)然后单击按钮时,行为也是正确的。然后,唯一不起作用的情况是当表格单元格编辑器处于 Activity 状态,然后单击另一个表格行中的按钮时。

比较两种情况下调用 actionPerformed 时的堆栈跟踪,我发现在错误的情况下 DefaultKeyboardFocusManager(KeyboardFocusManager).redispatchEventBasicButtonListener.focusLost(FocusEvent) ) 被调用,这对我来说看起来都很可疑。

这是我的问题的一些演示代码:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class TableButtonTest extends JFrame
{

    private JTable  table;

    public TableButtonTest()
    {
        super("TableButtonTest");

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel contentPane = new JPanel(new GridLayout(1, 0));
        contentPane.setOpaque(true);
        setContentPane(contentPane);

        table = new JTable(new MyTableModel());
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        add(table);

        setPreferredSize(new Dimension(600, 200));

        TableCellRenderer defaultBtnRenderer = new TableCellRenderer()
        {
            private JButton btn = new JButton("aa");

            public Component getTableCellRendererComponent(JTable _table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column)
            {
                return btn;
            }
        };

        table.getColumnModel().getColumn(0).setCellRenderer(defaultBtnRenderer);
        table.getColumnModel().getColumn(0).setCellEditor(new ButtonEditor());

        pack();
        setVisible(true);

    }

    public class ButtonEditor extends AbstractCellEditor implements TableCellEditor
    {
        private JButton btn = new JButton("bb");
        {
            btn.addActionListener(new ActionListener()
            {

                public void actionPerformed(ActionEvent e)
                {
                    System.out.println("BUTTON EVENT");
                }
            });
        }

        public Component getTableCellEditorComponent(JTable _table, Object value, boolean isSelected,
            int row, int column)
        {
            return btn;
        }

        public Object getCellEditorValue()
        {
            return null;
        }
    }

    class MyTableModel extends AbstractTableModel
    {
        public int getColumnCount()
        {
            return 1;
        }

        public int getRowCount()
        {
            return 5;
        }

        public Object getValueAt(int row, int col)
        {
            return null;
        }

        @Override
        public boolean isCellEditable(int row, int col)
        {
            return true;
        }
    }

    public static void main(String[] args)
    {
        new TableButtonTest();
    }
}

当您启动程序并点击任何“aa”按钮时,它会变成“bb”(表示显示编辑器而不是渲染器),并且当您释放鼠标按钮时,会打印“BUTTON EVENT”标准输出。如果您单击另一行中的另一个按钮,它也会变成“bb”,但在释放鼠标按钮之前“BUTTON EVENT”已打印到 STDOUT。而且按钮文本周围的焦点矩形也不会显示。

我使用 Java 1.6.0_26 和 1.6.0_27 测试了此行为。当我使用 1.5.0_17 时,情况变得更糟:当单击第二个按钮时,没有调用任何 actionPerformed,只显示“bb”按钮。第三次点击再次正常工作,第四次则无法正常工作,依此类推。因此,与 Java 1.6 的区别在于,在 1.6 上,释放鼠标按钮时会调用第二次(和第四次……)单击 actionPerformed,而在 1.5 上则根本不会调用。

但我不关心 1.5,我只想它能与 1.6 一起使用。

我该怎么做才能让这项工作成功?

谢谢。

最佳答案

Table Button Column显示了我使用按钮作为渲染器/编辑器的解决方案。

关于java - 在 JButton 上执行 actionPerformed,因为 TableCellEditor 在 MouseDown 上错误地调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7809556/

相关文章:

java - Guava Multimaps 通配符 putAll

java - 增强 Java 8 的库,同时保持向后兼容性

Java消耗太多内存

JAVA。 JFrame 中的背景图像、drawString、JButton 和 JComboBox

java - 如何为需要不同方法参数的按钮使用一个 Action 监听器?

java - JTable 中的 JButton 单击时不显示动画

java - 如何将AWS Lambda函数的结果返回到Android应用程序?

java - Jbutton 与 Jpanel 和 JFrame 之间的区别?

java - 使用 GridLayout 时如何将组件的大小锁定在可调整大小的框架中?

java - 如何在菜单项操作后删除 JTabbedPane 的内容