Swing JTabbedPane在填充时抛出IndexOutOfBoundsException

我有一个包含多个组件的应用程序。 其中一个是JTabbedPane ,其中包含其他内容(显然)。 我通过此getter访问此窗格:

 public JTabbedPane getPlotTabbedPane() { if (plotTabs == null) { plotTabs = new JTabbedPane(); plotTabs.setFocusable(false); plotTabs.add("Measurement", getPlotPanel()); plotTabs.add("Time", getPlotPanel().getTimePanel()); plotTabs.add("Data", getPlotPanel().getDataPanel()); plotTabs.add("Statistics", getPlotPanel().getStatisticsPanel()); plotTabs.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { getPlotPanel().refreshRenderer(); } }); } return plotTabs; } 

所以第一次,我访问它(即它尚未创建),我创建它,所有其他时间,我只是回馈已经创建的JTabbedPane 。 我已经被告知这不是最好的技术(如果有人能告诉我一个更好的不会弄乱布局组成代码的话,我非常乐于接受建议)。

现在,这完全正常 – 比方说 – 99%的案例(应用程序启动)。 在1%我得到一个

 Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: -1 at java.util.Vector.elementAt(Vector.java:430) at javax.swing.JTabbedPane.getTitleAt(JTabbedPane.java:1091) at javax.swing.plaf.basic.BasicTabbedPaneUI$Handler.updateHtmlViews(BasicTabbedPaneUI.java:3564) at javax.swing.plaf.basic.BasicTabbedPaneUI$Handler.componentAdded(BasicTabbedPaneUI.java:3699) at java.awt.Container.processContainerEvent(Container.java:2065) at java.awt.Container.processEvent(Container.java:2036) at java.awt.Component.dispatchEventImpl(Component.java:4653) at java.awt.Container.dispatchEventImpl(Container.java:2097) at java.awt.Component.dispatchEvent(Component.java:4481) at java.awt.Container.addImpl(Container.java:1083) at javax.swing.JTabbedPane.insertTab(JTabbedPane.java:703) at javax.swing.JTabbedPane.addTab(JTabbedPane.java:777) at javax.swing.JTabbedPane.add(JTabbedPane.java:814) at companyname.product.gui.Tab.getPlotTabbedPane(Tab.java:386) at companyname.product.gui.Tab.getFullPlotPanel(Tab.java:374) at companyname.product.gui.Tab.initComponents(Tab.java:262) at companyname.product.gui.Tab.(Tab.java:80) 

我不会进一步向下,但这基本上是GUI的创建。 Tab是一个扩展的JPanel 。 我无法弄明白,问题是什么,也无法阻止它。 显然,我可以在一个try/catch包装Tab.java的第386行,但这并没有解决问题,它只是解决了症状……

所以,你知道问题是什么,我怎么解决它或者我应该怎么做?

堆栈跟踪似乎建议您从另一个线程然后事件调度线程(EDT)访问Swing组件。 这是不允许的。

我很确定你是否确保只从正确的线程访问Swing组件,你将不再看到这个例外。

更多信息可以在Swurrency中的Concurrency教程中找到。 您还可以查看包含RepaintManager 本文 ,它可以帮助您检测Swing线程违规