2

如果选择了其他一些元素,我正在尝试创建更改其元素的 GUI。按下按钮后,它应该禁用自身并打开另一个。但是 JButton 有时不能自行禁用。它抛出:java.lang.IllegalArgumentException:比较方法违反了它的一般合同!

它与错误有关:6923200:swing LayoutComparator 破坏了可能导致 IllegalArgumentException 的传递性

建议在eclipse ini中添加一行:java.util.Arrays.useLegacyMergeSort=true 但它不起作用。您知道上述问题的任何解决方法吗?

^编辑:在我看来,在 actionPerformed() 方法中两次更改按钮状态是不可能的。

^ EDIT2:SSCCE - 我希望:)

public void actionPerformed(ActionEvent e) {
    enableButtons(0, 0, 0, 0); //0 disables, 1 enables one of four buttons
    someFunction();
    enableButtons(1, 1, 0, 0);
}

它崩溃了:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.util.TimSort.mergeLo(Unknown Source)
    at java.util.TimSort.mergeAt(Unknown Source)
    at java.util.TimSort.mergeCollapse(Unknown Source)
    at java.util.TimSort.sort(Unknown Source)
    at java.util.TimSort.sort(Unknown Source)
    at java.util.Arrays.sort(Unknown Source)
    at java.util.Collections.sort(Unknown Source)
    at javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(Unknown Source)
    at javax.swing.SortingFocusTraversalPolicy.getFocusTraversalCycle(Unknown Source)
    at javax.swing.SortingFocusTraversalPolicy.getComponentAfter(Unknown Source)
    at javax.swing.LayoutFocusTraversalPolicy.getComponentAfter(Unknown Source)
    at java.awt.Component.getNextFocusCandidate(Unknown Source)
    at java.awt.Component.transferFocus(Unknown Source)
    at java.awt.Component.disable(Unknown Source)
    at javax.swing.JComponent.disable(Unknown Source)
    at java.awt.Component.enable(Unknown Source)
    at java.awt.Component.setEnabled(Unknown Source)
    at javax.swing.JComponent.setEnabled(Unknown Source)
    at javax.swing.AbstractButton.setEnabled(Unknown Source)
    at CWindow.enableButtons(CWindow.java:83)
    at CWindow$2.actionPerformed(CWindow.java:254)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
4

1 回答 1

1

一方面,someFunction()不应该在actionPerformed()方法中直接在 EDT 上运行。正确的模式如下所示:

public void actionPerformed(ActionEvent e) {
    enableButtons(0, 0, 0, 0); //0 disables, 1 enables one of four buttons
    Thread worker = new Thread(){
        public void run(){
            someFunction();
            SwingUtilities.invokeLater(new Runnable(){
                public void run(){
                    enableButtons(1, 1, 0, 0);
                }
            });
        }
    }
    worker.start();
}

你可能会问为什么需要双重嵌套的匿名类。首先,耗时的任务不应该在 EDT 上运行,因为它们会阻塞整个 GUI。这就是线程工作者的作用——我们在它自己的线程中运行任务。但是当任务完成时,我们想要重新启用一些按钮——但是该任务操作 Swing 组件并且必须在 EDT 中运行。这就是 SwingUtilities.invokeLater() 的用途——它允许 EDT 处理 Runnable。

尝试通过我的示例修改代码,看看是否可以解决您的问题。

于 2013-05-31T23:32:02.580 回答