3

方法があることは知っていますが、SwingUtilities.updateComponentTreeUI(Component c)完全には機能しません。たとえば、私は を持っていJFileChooserて、現在のルック アンド フィールは Windows です。その後、ルック アンド フィールを Nimbus に変更するSwingUtilities.updateComponentTreeUI(mainWindow)と、メイン ウィンドウのスタイルは正しく変更されますが、JFileChooser.showOpenDialog(Component parent)メソッドでファイル チューザーを表示すると、まだ Windows のままです。見て、感じてください。メソッドでポップアップダイアログを表示すると、同じことが起こりJPopupMenu.show(Component invoker, int x, int y)ます。

この問題の解決策はありますか?

4

2 に答える 2

6

これが新しいルック アンド フィールのクラス名であると仮定するとvalue、すべてのウィンドウとサブコンポーネントを更新するためのスニペットは次のようになります。

public static void updateLAF(String value) {
    if (UIManager.getLookAndFeel().getClass().getName().equals(value)) {
        return;
    }
    try {
        UIManager.setLookAndFeel(value);
        for (Frame frame : Frame.getFrames()) {
            updateLAFRecursively(frame);
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnsupportedLookAndFeelException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public static void updateLAFRecursively(Window window) {
    for (Window childWindow : window.getOwnedWindows()) {
        updateLAFRecursively(childWindow);
    }
    SwingUtilities.updateComponentTreeUI(window);
}
于 2013-04-23T09:26:19.820 に答える
5

を呼び出すSwingUtilities.updateComponentTreeUI(mainWindow)と、下の Swing 階層内の Swing コンポーネントのみが更新されmainWindowます。

チューザーをJFileChooser表示せずにコード内のどこかに (クラスのフィールドなど) を格納すると、呼び出しによって更新されません。これを回避するには、自分自身にリスナーを追加し、ルック アンド フィールが変更されたときにそのリスナーから呼び出します。JFileChooserSwingUtilities.updateComponentTreeUI(mainWindow)UIManagerSwingUtilities.updateComponentTreeUI(myStoredFileChooser)

これでメモリ リークが発生しないように注意してください。たとえば、そのリスナーにはWeakReferencetoのみを持たせますJFileChooser(UIManager の有効期間は JVM の有効期間と等しいため)。

于 2013-04-23T09:22:18.797 に答える