1

我在我的应用程序中使用了 JTabbedPane 并监听它的变化,ChangeListener这样我就可以知道当前选择了哪个选项卡。所以我的stateChanged方法是;

public void stateChanged(ChangeEvent e) {
    currentPageIndex = jTabbedPane.getSelectedIndex();
}

但是,当我向JTabbedPane它添加新选项卡时,它会在上面的方法中抛出一个ArrayIndexOutOfBoundsException,我不知道为什么。对于类似的情况,有人建议这是一个错误http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4873983,但正如您将看到的那样,解决方案是使用 EventDispatchThread 中的 Swing。

这是什么意思,他们是这个意思SwingUtilities.invokeLater吗?有人可以告诉我如何stateChanged相应地修改我的方法以避免异常吗?

编辑:下面是我的addTab()方法。这在程序开始时被多次调用,并且它“有时”触发stateChanged()方法。并且在某些时候stateChanged()会导致异常。这就是我从调试器到现在所能知道的。我知道这似乎不太清楚,所以如果您以前没有听说过这种事情,那没关系,感谢您的努力。但我认为这可能与我上面给出的链接有关。

void addTab(EJournal eJournalModel,int index, String pageName) {
    SectionPage newPage = new SectionPage(jTabbedPane.getSize(), controller, eJournalModel.getSections().get(currentPageIndex));
    JScrollPane scrollPane = new JScrollPane(newPage);
    scrollPanes.add(index, scrollPane);
    sectionPages.add(index, newPage);
    jTabbedPane.insertTab(pageName, idleIcon, scrollPane, null, index);
    jTabbedPane.updateUI();
}

Edit2:抛出此异常。在我的方法真正完成执行并且完成之后, anactionPerformed()被触发,然后是一大堆东西,然后是异常。

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0
        at javax.swing.plaf.basic.BasicTabbedPaneUI.tabForCoordinate(BasicTabbedPaneUI.java:1488)
        at javax.swing.plaf.basic.BasicTabbedPaneUI.setRolloverTab(BasicTabbedPaneUI.java:558)
        at javax.swing.plaf.basic.BasicTabbedPaneUI.access$2000(BasicTabbedPaneUI.java:37)
        at javax.swing.plaf.basic.BasicTabbedPaneUI$Handler.mouseEntered(BasicTabbedPaneUI.java:3604)
        at java.awt.Component.processMouseEvent(Component.java:6272)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3255)
        at java.awt.Component.processEvent(Component.java:6028)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
        at java.awt.LightweightDispatcher.trackMouseEnterExit(Container.java:4363)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4220)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2475)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
4

3 回答 3

3

最可能的答案是您正在从非 EDT 线程更改 Swing 中的某些内容。任何涉及 Swing 组件或 Swing 组件使用的模型的东西都必须在 EDT 上执行。这包括构建 Swing 对象和模型。

找到这类非 EDT 操作的最简单的方法是使用 Substance 外观和感觉运行。转到Substance 网站并单击“获取”。下载 Substance 和 Trident 库,将它们添加到您的类路径,然后使用选项启动 JVM

-Dswing.defaultlaf=org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel

Substance坚持认为摇摆动作发生在 EDT 上。如果您在另一个线程中执行某些操作,它将引发异常。最好的部分是,由于异常发生在任何事件被调度之前,有问题的代码仍然在堆栈上。这使您可以在真正发生错误的地方尝试回溯多个pumpEvent堆栈。

注意: 物质不是仔细编码的替代品。在某些情况下,它可能无法检测到模型的非 EDT 更改。物质只是让它更容易。

于 2010-05-02T18:13:45.337 回答
2

我建议启动调试器并单步执行您的代码,直到您到达引发异常的地步。看看是什么值导致了这种情况并开始向后工作。

从您发布的三行代码中可以看出。是

currentPageIndex = jTabbedPane.getSelectedIndex();

监听器实现的数据成员?

index你传入的值是多少?

于 2010-05-01T21:12:45.653 回答
0

您没有发布 SSCCE。5 行代码不是 SSCCE。

一方面,您不应该使用updateUI()方法。我不知道为什么我在发布的代码中经常看到这种情况。

于 2010-05-01T21:45:41.377 回答