2010-05-01 74 views
1

我在我的應用程序中使用JTabbedPane,並且我傾聽它的更改ChangeListener,以便我可以知道當前選擇了哪個選項卡。 所以我的stateChanged方法是;使用JTabbedPane時拋出的異常

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) 
+1

如果建議是嘗試使用SwingUtilities.invokeLater,那麼爲什麼不先試試呢?如果它運作良好。如果沒有,那麼我們將不知道再次提示。如果您之前從未使用過此方法,請搜索論壇或網絡上的示例。如果你仍然有問題,然後張貼您的SSCCE:http://sscce.org – camickr 2010-05-01 21:08:46

回答

0

您沒有發佈SSCCE。 5行代碼不是SSCCE。

一方面,您不應該使用updateUI()方法。我不知道爲什麼我經常在發佈的代碼中看到這個。

+0

我不應該使用updateUI()?我應該使用什麼? – Halo 2010-05-02 11:16:59

+0

我刪除了updateUI(),它現在不會引發異常。 – Halo 2010-05-02 11:37:07

+0

我會說,因爲你的回答有點侵略性,缺乏任何解釋。抱怨說你到處看到updateUI()並不能解釋爲什麼他不應該使用它。 – Gnoupi 2010-05-03 07:35:51

2

我建議啓動一個調試器並逐步執行代碼,直到達到拋出異常的地步。看看造成這種情況的原因是什麼,並開始反向工作。

從您發佈的三行代碼中可以看出。是

currentPageIndex = jTabbedPane.getSelectedIndex(); 

您的Listener實現的數據成員?

傳入的index的值是多少?

+0

謝謝,我正在步進,但我真的失去了事件的跟蹤:)它只是不斷跳過API,一切都應該結束。 – Halo 2010-05-01 21:28:55

+0

也許您只需要一個ChangeListener,即可輕鬆觸發的選項卡。 – duffymo 2010-05-01 21:30:14

+0

在程序開始時,我創建了三個面板並將其添加到JTabbedPane。調用方法實際完成後,會觸發一些調度事件,processMouse事件和..讓我寫出異常的問題。 – Halo 2010-05-01 21:34:47

3

最可能的答案是你正在改變從非EDT線程Swing中的東西。任何觸及Swing組件的模型或Swing組件使用的模型必須在EDT上執行。這包括構建Swing對象和模型。

找到這些非EDT動作的簡單方法是使用物質外觀和感覺來運行。轉到Substance web site並點擊「獲取」。下載物質和Trident庫,將它們添加到您的類路徑,然後選擇啓動JVM

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

物質非常堅持認爲,擺動動作發生在EDT。它會拋出一個異常,如果你做另一個線程。最好的部分是,因爲在發送任何事件之前發生異常,違規代碼仍然在堆棧中。這可以讓你發現錯誤的地方,而不是試圖通過多個pumpEvent堆棧回溯。

注意:物質不是精心編碼的替代品。有些情況下,它可能無法檢測模型的非EDT更改。物質只是讓它更容易。

+0

謝謝你解答問題的答案,而且不僅像另一個那樣居高臨下。這種例外的確很像是在Swing組件上同時修改的情況。 (改變另一個線程上的Swing組件上的東西,而不是EDT,如果EDT在同一時刻觸發重繪,確實可能會產生問題。此外,感謝Substance鏈接,不知道那個。 – Gnoupi 2010-05-03 07:34:57

+0

謝謝你,也爲鏈接。 – Halo 2010-05-03 08:15:43