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代码存储在某处(例如,在类的字段中)而不显示JFileChooser选择器,则调用将不会更新SwingUtilities.updateComponentTreeUI(mainWindow)。您可以通过向您自己添加一个侦听器并在外观更改时从该侦听器UIManager调用来解决此问题。SwingUtilities.updateComponentTreeUI(myStoredFileChooser)

确保你不会用这个创建内存泄漏,例如让那个监听器只有一个WeakReferenceJFileChooser因为 UIManager 的生命周期等于 JVM 的生命周期)

于 2013-04-23T09:22:18.797 回答