使用JTabbedPane时抛出异常

时间:2010-05-01 20:53:49

标签: java swing exception jtabbedpane

我在我的应用程序中使用了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:抛出此异常。在我的方法实际完成执行并且evertying完成后,actionPerformed()被触发,然后是一大堆东西然后异常。

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)

3 个答案:

答案 0 :(得分:3)

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

找到这种非EDT动作的最轻松的方法是运行物质外观和感觉。转到Substance web site,然后点击“获取”。下载Substance和Trident库,将它们添加到类路径中,然后使用选项

启动JVM
-Dswing.defaultlaf=org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel

物质非常坚持认为,挥杆动作发生在EDT上。如果你做另一个线程,它会抛出异常。最好的部分是,因为异常发生在调度任何事件之前,违规代码仍然在堆栈上。这可以让您在错误发生的地方反而试图回溯多个pumpEvent堆栈。

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

答案 1 :(得分:2)

我建议启动调试器并逐步执行代码,直到达到抛出异常的程度。查看导致此问题的值并开始向后工作。

可以从三行代码中了解您发布的内容。是

currentPageIndex = jTabbedPane.getSelectedIndex();

Listener实现的数据成员?

您传递的index的价值是多少?

答案 2 :(得分:0)

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

首先,您不应该使用 updateUI()方法。我不知道为什么我会在发布的代码中经常看到这个。