Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java MouseDown错误调用TableCellEditor时对JButton执行的操作_Java_Swing_Jbutton_Actionlistener_Tablecelleditor - Fatal编程技术网

Java MouseDown错误调用TableCellEditor时对JButton执行的操作

Java MouseDown错误调用TableCellEditor时对JButton执行的操作,java,swing,jbutton,actionlistener,tablecelleditor,Java,Swing,Jbutton,Actionlistener,Tablecelleditor,我正在尝试将JButton用作TableCellRenderer和TableCellEditor用于我的JTable。在我的测试场景中,我有5行,每行显示一个JButton作为渲染器和编辑器(编辑器和渲染器的不同按钮实例)。当我第一次单击一个按钮时,当我释放鼠标按钮时,将调用编辑器按钮的actionPerformed。当我单击另一行中的另一个按钮时,当我按下鼠标按钮(鼠标按下)时,编辑器按钮的actionPerformed-事件已经被调用。这种行为似乎不对。通常在释放鼠标按钮时调用actionP

我正在尝试将
JButton
用作
TableCellRenderer
TableCellEditor
用于我的
JTable
。在我的测试场景中,我有5行,每行显示一个
JButton
作为渲染器和编辑器(编辑器和渲染器的不同按钮实例)。当我第一次单击一个按钮时,当我释放鼠标按钮时,将调用编辑器按钮的
actionPerformed
。当我单击另一行中的另一个按钮时,当我按下鼠标按钮(
鼠标按下
)时,编辑器按钮的
actionPerformed
-事件已经被调用。这种行为似乎不对。通常在释放鼠标按钮时调用
actionPerformed
-事件,而不是在按下鼠标按钮时调用。之后按另一行中的另一个按钮时,释放鼠标按钮时再次正确调用
actionPerformed
,在下一行中单击
actionPerformed
时再次(错误地)调用
mouse\u DOWN
,依此类推

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

比较两种情况下调用
actionPerformed
时的堆栈跟踪,我发现在不正确的情况下调用了
DefaultKeyboardFocusManager(KeyboardFocusManager)。redispatchEvent
BasicButtonListener.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”,但在释放鼠标按钮之前,“按钮事件”已打印到标准输出。而且按钮文本周围的焦点矩形也不会显示

我用Java1.6.0_26和1.6.0_27测试了这种行为。当我使用1.5.0_17时,事件变得更糟:当单击第二个按钮时,没有调用actionPerformed,只显示“bb”按钮。第三次点击再次正常工作,第四次没有,依此类推。因此,与Java1.6的不同之处在于,在1.6上,第二次(和第四次,…)单击actionPerformed时会在释放鼠标按钮时调用,而在1.5上则根本不会调用

但是我不在乎1.5,我只想让它和1.6一起工作

我能做些什么来让它工作


谢谢。

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

据我所知,有ActionListeners的外观实现,还有MouseListeners的更系统通用的实现。这可以解释API生成之间的差异。。。这是没有来源的,所以我留下来作为评论另外,你能简单地使用鼠标侦听器而不是ActionListener吗?我知道人们普遍不赞成使用低级听众,但这可能就是一个例子。