Java PropertyChangeListener内的JOptionPane.showMessageDialog导致意外行为

Java PropertyChangeListener内的JOptionPane.showMessageDialog导致意外行为,java,swing,Java,Swing,我已经用JCheckBoxMenuItem创建了一个可检查的菜单项。我试图做的是,当复选框被选中时,会出现一条消息: JCheckBoxMenuItem checkbox = new JCheckBoxMenuItem("Checkbox"); checkbox.addPropertyChangeListener(evt -> { boolean isCheck = ((JCheckBoxMenuItem) evt.getSource()).isSelected(

我已经用
JCheckBoxMenuItem
创建了一个可检查的菜单项。我试图做的是,当复选框被选中时,会出现一条消息:

 JCheckBoxMenuItem checkbox = new JCheckBoxMenuItem("Checkbox");
    checkbox.addPropertyChangeListener(evt -> {
        boolean isCheck = ((JCheckBoxMenuItem) evt.getSource()).isSelected();
        if(isCheck){
            JOptionPane.showMessageDialog(null, "You checked the checkbox", "Information", JOptionPane.INFORMATION_MESSAGE);
        }
    });
但是,当我尝试选中复选框时,没有显示任何内容。第二次单击
JMenu
时,会出现一组模态,并导致出现
ArrayIndexOutOfBoundsException

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Vector.java:474)
at javax.swing.MenuSelectionManager.setSelectedPath(MenuSelectionManager.java:117)
at javax.swing.MenuSelectionManager.clearSelectedPath(MenuSelectionManager.java:151)
at javax.swing.plaf.basic.BasicPopupMenuUI$MouseGrabber.cancelPopupMenu(BasicPopupMenuUI.java:917)
at javax.swing.plaf.basic.BasicPopupMenuUI$MouseGrabber.eventDispatched(BasicPopupMenuUI.java:828)
at java.awt.Toolkit$SelectiveAWTEventListener.eventDispatched(Toolkit.java:2425)
at java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Toolkit.java:2317)
at java.awt.Toolkit.notifyAWTEventListeners(Toolkit.java:2275)
at java.awt.Component.dispatchEventImpl(Component.java:4777)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Window.dispatchEventImpl(Window.java:2750)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:109)  
...

发生这种情况的原因是什么?

您应该首先检查JOptioanPane或侦听器是否存在问题。您可以使用
System.out.println(“check=“+check”)首先,而不是显示
作业窗格
。如果没有问题,则更改
侦听器
类型

您应该首先检查
JOptioanPane
或侦听器是否存在问题。您可以使用
System.out.println(“check=“+check”)首先,而不是显示
作业窗格
。如果没有问题,则更改
侦听器
类型

是什么导致了这种情况


您使用了错误的侦听器执行错误的任务
PropertyChangeListener
不是您想要实现的目标的合适的侦听器,相反,您应该使用
ActionListener

JCheckBoxMenuItem checkbox = new JCheckBoxMenuItem("Checkbox");
checkbox.addActionListener((ActionEvent e) -> {
        boolean isCheck = ((JCheckBoxMenuItem)e.getSource()).isSelected();
        if (isCheck) {
            JOptionPane.showMessageDialog(null, "You checked the checkbox", "Information", JOptionPane.INFORMATION_MESSAGE);
        }
});

PropertyChangeListener
JCheckBoxMenuItem
的选定状态更改时,实际上(至少在我的测试中)不会触发任何事件,但您的代码确实导致它不断抛出一个对话框,迫使我终止程序

请查看,并获取更多详细信息

是什么导致了这种情况


您使用了错误的侦听器执行错误的任务
PropertyChangeListener
不是您想要实现的目标的合适的侦听器,相反,您应该使用
ActionListener

JCheckBoxMenuItem checkbox = new JCheckBoxMenuItem("Checkbox");
checkbox.addActionListener((ActionEvent e) -> {
        boolean isCheck = ((JCheckBoxMenuItem)e.getSource()).isSelected();
        if (isCheck) {
            JOptionPane.showMessageDialog(null, "You checked the checkbox", "Information", JOptionPane.INFORMATION_MESSAGE);
        }
});

PropertyChangeListener
JCheckBoxMenuItem
的选定状态更改时,实际上(至少在我的测试中)不会触发任何事件,但您的代码确实导致它不断抛出一个对话框,迫使我终止程序


请看一看,有关更多详细信息,

PropertyChangeListener
不是在本例中使用的合适的侦听器,
ActionListener
将是better@MadProgrammer啊,谢谢!它现在可以工作了,但是它们之间有什么区别呢?
ActionListener
是按钮API使用的通用侦听器(特别是,但不是唯一的),用于提供按钮何时触发的通知,而不管按钮是如何触发的。
PropertyChangeListener
通常用于支持bean API,但如果您知道要侦听什么,则可以将其用于其他一些“常规”通知
PropertyChangeListener
不是合适的侦听器。在这种情况下,可以使用
ActionListener
better@MadProgrammer啊,谢谢!它现在可以工作了,但是它们之间有什么区别呢?
ActionListener
是按钮API使用的通用侦听器(特别是,但不是唯一的),用于提供按钮何时触发的通知,而不管按钮是如何触发的。
PropertyChangeListener
通常用于支持BeanAPI,但如果您知道要侦听什么,它也可以用于其他一些“常规”通知