1

複数の独自の UI (JTabbedPane など) を使用する Java Swing アプリケーションでは、起動直後に、アプリケーション全体のルック アンド フィール (L&F) がデフォルトに戻ることがあります。すぐにすべてが正しく表示され、1 秒以内にアプリケーション全体が醜いデフォルトに変わります。

残念ながら、これを再現するのは困難です。java-1.6.0-openjdk-amd64を使用してEclipse内から直接起動した場合、これは非常にまれに発生し、これまでのところUbuntuでのみ発生します。新しい Java バージョンもインストールしていますが、1.6 を使用して互換性をテストしています。

これはすべてのコンポーネントに対して発生するか、まったくコンポーネントに対して発生しないため、II がどのように UI を導出するかは問題ではないように見えます。カスタム UI が使用されていないこの小さな変更も元に戻します。

JTextField textField = new JTextField();
textField.setBorder(null);

その場合、境界線が表示されます。

これは再現が難しいため、常に発生するコード例を示すことはできません。実際、上記はすでに例ですが、常に発生するとは限りません。しかし、L&F または L&F への変更が突然不必要にデフォルトに戻ったという同様の問題に遭遇した人を見つけたいと思っています。もしそうなら、あなたの経験とできれば解決策を共有していただければ幸いです。

---------------- 編集: 2 つの回避策が見つかりました:

  1. 境界線の問題については、textField.setBorder(new EmptyBorder());null に設定する代わりに単純に使用します。
  2. updateUI への望ましくない呼び出しによって実際に引き起こされた UI のリセットのために、updateUI() をオーバーライドするカスタマイズされたスイング オブジェクトのサブクラスを作成しました。

    public class JTabbedPaneNoHeads extends JTabbedPane {
        public JTabbedPaneNoHeads() {
            setUI(new GUITabbedPaneNoHeadsUI());
        }
    
        @Override
        public GUITabbedPaneNoHeadsUI getUI() {
            return (GUITabbedPaneNoHeadsUI) ui;
        }
    
        @Override
        public void updateUI() {
            /* This was to find out who is calling updateUI:
                        StackTraceElement[] _stackTrace = Thread.currentThread().getStackTrace();
                        for (StackTraceElement element : _stackTrace ){
                            System.out.print(element + " -- ");
                        }
                        System.out.println();
            */
            setUI(new GUITabbedPaneNoHeadsUI());
        }
    }
    

今、すべてが正常に動作します。

ところで: updateUI の呼び出しには、次のスタック トレースがありました (上記のコードのコメント ブロックによって生成されます)。

livedocket.GUI.design.JTabbedPaneNoHeads.updateUI(JTabbedPaneNoHeads.java:22)
javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1230)
.... many more of these updateComponentTreeUI0 ...
javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1245)
javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1221)
javax.swing.plaf.metal.MetalLookAndFeel$AATextListener.updateWindowUI(MetalLookAndFeel.java:2329)
javax.swing.plaf.metal.MetalLookAndFeel$AATextListener.updateAllUIs(MetalLookAndFeel.java:2342)
javax.swing.plaf.metal.MetalLookAndFeel$AATextListener.access$200(MetalLookAndFeel.java:2295)
javax.swing.plaf.metal.MetalLookAndFeel$AATextListener$1.run(MetalLookAndFeel.java:2370)
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:226)
java.awt.EventQueue.dispatchEventImpl(EventQueue.java:673)
java.awt.EventQueue.access$300(EventQueue.java:96)
java.awt.EventQueue$2.run(EventQueue.java:634)
java.awt.EventQueue$2.run(EventQueue.java:632)
java.security.AccessController.doPrivileged(Native Method)
java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:108)
java.awt.EventQueue.dispatchEvent(EventQueue.java:643)
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
java.awt.EventDispatchThread.run(EventDispatchThread.java:138)

前述したように、これらの呼び出しはごくまれにしか発生せず、Java 1.6 でのみ発生します。

4

1 に答える 1

1

スレッド化に問題があるアプリケーションで同様の症状を見たことがあります。私であれば、すべての GUI がイベント ディスパッチ スレッドで構築されているかどうかを再確認します。

于 2013-09-14T10:21:07.080 に答える