1

複数のコンポーネントを含むアプリケーションがあります。そのうちの 1 つは、その中JTabbedPaneに他のものが含まれています (明らかに)。このゲッターを介してのみこのペインにアクセスします。

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.<init>(Tab.java:80)

スタックをさらに下に移動することはしませんが、これは基本的に GUI の作成です。Tab拡張JPanelです。問題が何であるか、それを防ぐために何ができるかを本当に理解することはできません。明らかに、Tab.java の 386 行目を でラップすることもできますが、それではtry/catch問題は解決しません。症状が解決するだけです...

では、何が問題なのか、どうすれば解決できるのか、どうすればよいのか分かりますか?

4

1 に答える 1

3

スタックトレースは、別のスレッド、次にイベント ディスパッチ スレッド (EDT) から Swing コンポーネントにアクセスすることを示唆しているようです。これは許可されていません。

正しいスレッドからのみ Swing コンポーネントにアクセスするようにすれば、この例外は表示されなくなると確信しています。

詳細については、Swing の同時実行のチュートリアルを参照してください。また、Swing スレッド違反の検出に役立つ記事が含まれているこの記事も参照してください。RepaintManager

于 2012-07-20T12:49:00.177 に答える