首页 > 解决方案 > SwingUtilities.updateComponentTreeUI() 不改变 JFrames 标题栏

问题描述

环境:

使用 Netbeans 8.1

甲骨文 JDK 1.8

赢 10 专业版

语境:

带有 JCheckBoxMenuItem 的 GUI,用于在运行时更改 LookAndFeel(LAF)。

darkLAF= JTattoo的 HiFi LAF

defaultLAF=Sun 的 Windows LAF(com.sun.java.swing.plaf.windows.WindowsLookAndFeel)

问题:

  1. GUI 使用 defaultLAF 启动(在 EDT 中)。用户更改为 darkLAF ..标题栏应该已经改变了..它没有。

  2. 当用户切换回 defaultLAF 时,JMenuItems(File and Edit) 显示较灰的背景,而不是 defaultLAF 样式。

截图:

  1. 启动的 defaultLAF

  2. 切换到 darkLAF 后

  3. 用户切换回 defaultLAF
  4. 预期寻找darkLAF

代码:

  1. 在 JCheckBoxMenuItem 的 itemStateChangeListener 内部

    try{
       if (checkBox.isSelected())                                                                 
          UIManager.setLookAndFeel(darkLookAndFeel);
       else
        UIManager.setLookAndFeel(defaultLookAndFeel);
    
    
    } catch (UnsupportedLookAndFeelException ex) {
       //handle err
    }
    
    //GUI is a class extending JFrame        
    SwingUtilities.updateComponentTreeUI(this);
    //some JFileChooser
    SwingUtilities.updateComponentTreeUI(fc);
    
    pack();
    

抓住:

  1. 不应要求用户重新启动 GUI。

标签: javaswinglook-and-feel

解决方案


这有点难,但我找到了解决方案。

切换到 JTatto L&F 所需的步骤

  1. 处置窗口
  2. 设置 L&F
  3. 将根窗格的窗口样式设置为JRootPane.FRAME
  4. 更新用户界面
  5. 使框架不装饰
  6. 使框架可见

切换回 Windows L&F 所需的步骤

  1. 处置窗口
  2. 设置 L&F
  3. 更新用户界面
  4. 使框架装饰
  5. 使框架可见

这是代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MinFrame extends JFrame {

    public MinFrame() {
        super("Minimal-Frame-Application");

        // setup menu
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("File");
        menu.setMnemonic('F');
        JMenuItem menuItem = new JMenuItem("Exit");
        menuItem.setMnemonic('x');
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.ALT_MASK));
        menuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                System.exit(0);
            }
        });
        menu.add(menuItem);
        menuBar.add(menu);
        setJMenuBar(menuBar);

        // setup widgets
        JPanel contentPanel = new JPanel(new BorderLayout());
        contentPanel.setBorder(BorderFactory.createEmptyBorder(0, 4, 4, 4));
        JScrollPane westPanel = new JScrollPane(new JTree());
        JEditorPane editor = new JEditorPane("text/plain", "Hello World");
        JScrollPane eastPanel = new JScrollPane(editor);
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, westPanel,eastPanel);
        splitPane.setDividerLocation(148);
        contentPanel.add(splitPane, BorderLayout.CENTER);


        AbstractButton winLF = new JButton("Windows");
        winLF.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    MinFrame.this.dispose();
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    SwingUtilities.updateComponentTreeUI(MinFrame.this.getRootPane());

                    MinFrame.this.setUndecorated(false);
                    MinFrame.this.setVisible(true);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
        AbstractButton customLF = new JButton("JTatto");
        customLF.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    MinFrame.this.dispose();
                    UIManager.setLookAndFeel("com.jtattoo.plaf.smart.SmartLookAndFeel");
                    MinFrame.this.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
                    SwingUtilities.updateComponentTreeUI(MinFrame.this.getRootPane());

                    MinFrame.this.setUndecorated(true);
                    MinFrame.this.setVisible(true);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });

        JPanel buttons = new JPanel();
        buttons.add(winLF);
        buttons.add(customLF);
        contentPanel.add(buttons, BorderLayout.SOUTH);
        setContentPane(contentPanel);

        // add listeners
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        // show application
        setLocation(32, 32);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400, 300);
        setVisible(true);
    } // end CTor MinFrame

    public static void main(String[] args) {
        try {
            // select Look and Feel
//            UIManager.setLookAndFeel("com.jtattoo.plaf.smart.SmartLookAndFeel");
            // start application
            new MinFrame();
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    } // end main

}

推荐阅读