问题
Environment:
Using Netbeans 8.1
Oracle JDK 1.8
Win 10 pro
Context:
A GUI with a JCheckBoxMenuItem to change LookAndFeel(LAF) at runtime.
darkLAF=JTattoo's HiFi LAF
defaultLAF=Sun's Windows LAF(com.sun.java.swing.plaf.windows.WindowsLookAndFeel)
Problem:
GUI launches(in EDT) with defaultLAF. User changes to darkLAF..the title bar should have changed..it doesn't.
When the user switches back to defaultLAF, the JMenuItems(File and Edit) show greyer backgrounds not the defaultLAF style.
Screenshots:
The launched defaultLAF
upon switching to darkLAF
- user switched back to defaultLAF
- expected look for darkLAF
Code:
Inside the itemStateChangeListener for JCheckBoxMenuItem
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();
Catch:
- User shouldn't be asked to do a GUI restart.
回答1:
It was a little bit hard, but I've found a solution.
Steps you need to switch to the JTatto L&F
- Dispose window
- Set L&F
- Set window style of root pane to
JRootPane.FRAME
- Update UI
- Make Frame undecorated
- Make Frame visible
Steps you need to switch back to Windows L&F
- Dispose window
- Set L&F
- Update UI
- Make Frame decorated
- Make Frame visible
Here is the code
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
}
来源:https://stackoverflow.com/questions/51595444/swingutilities-updatecomponenttreeui-not-changing-jframes-titlebar