PropertyChangeListener中的JOptionPane.showMessageDialog会导致意外行为

时间:2016-02-17 08:47:23

标签: java swing

我创建了一个带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)  
...

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

2 个答案:

答案 0 :(得分:4)

  

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

你正在使用错误的监听器来处理错误的工作。 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的选定状态发生变化时触发任何事件,但是您的代码确实导致它不断地抛出一个对话框强制我杀死程序

有关详细信息,请查看How to Use MenusHow to Use Buttons, Check Boxes, and Radio ButtonsHow to Write an Action Listeners

答案 1 :(得分:0)

您应首先检查gesture.cancelsTouchesInView = NO; 或听众的问题。您可以先使用JOptioanPane,而不是显示System.out.println("check="+check);。如果没有问题,请更改JOptionPane类型