SwingUtilities.updateComponentTreeUI() 不更改 JFrames 标题栏
SwingUtilities.updateComponentTreeUI() not changing JFrames titlebar
环境:
使用 Netbeans 8.1
甲骨文JDK1.8
Win 10 专业版
上下文:
带有 JCheckBoxMenuItem 的 GUI,可在运行时更改 LookAndFeel(LAF)。
darkLAF=JTattoo的HiFi LAF
defaultLAF=Sun 的 Windows LAF(com.sun.java.swing.plaf.windows.WindowsLookAndFeel)
问题:
GUI 使用 defaultLAF 启动(在美国东部时间)。用户更改为 darkLAF..标题栏应该已更改..但没有。
当用户切换回 defaultLAF 时,JMenuItems(文件和编辑)显示灰色背景而不是 defaultLAF 样式。
截图:
The launched defaultLAF
upon switching to darkLAF
- user switched back to defaultLAF
- expected look for darkLAF
代码:
在 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();
捕获:
- 不应要求用户重新启动 GUI。
有点难,但我找到了解决办法。
切换到 JTatto L&F 所需的步骤
- 处置window
- 设置 L&F
- 将根窗格的 window 样式设置为
JRootPane.FRAME
- 更新UI
- 不修饰框架
- 使框架可见
您需要切换回 Windows L&F
的步骤
- 处置window
- 设置 L&F
- 更新UI
- 装饰相框
- 使框架可见
这是代码
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
}
环境:
使用 Netbeans 8.1
甲骨文JDK1.8
Win 10 专业版
上下文:
带有 JCheckBoxMenuItem 的 GUI,可在运行时更改 LookAndFeel(LAF)。
darkLAF=JTattoo的HiFi LAF
defaultLAF=Sun 的 Windows LAF(com.sun.java.swing.plaf.windows.WindowsLookAndFeel)
问题:
GUI 使用 defaultLAF 启动(在美国东部时间)。用户更改为 darkLAF..标题栏应该已更改..但没有。
当用户切换回 defaultLAF 时,JMenuItems(文件和编辑)显示灰色背景而不是 defaultLAF 样式。
截图:
The launched defaultLAF
upon switching to darkLAF
- user switched back to defaultLAF
- expected look for darkLAF
代码:
在 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();
捕获:
- 不应要求用户重新启动 GUI。
有点难,但我找到了解决办法。
切换到 JTatto L&F 所需的步骤
- 处置window
- 设置 L&F
- 将根窗格的 window 样式设置为
JRootPane.FRAME
- 更新UI
- 不修饰框架
- 使框架可见
您需要切换回 Windows L&F
的步骤- 处置window
- 设置 L&F
- 更新UI
- 装饰相框
- 使框架可见
这是代码
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
}