我正在构建一个 java 应用程序,我想在运行时使用这些单选按钮更改应用程序的主题(外观)。我不知道该怎么做!
提前致谢!
我正在构建一个 java 应用程序,我想在运行时使用这些单选按钮更改应用程序的主题(外观)。我不知道该怎么做!
提前致谢!
您可以通过调用SwingUtilities.updateTreeComponentUI(frame)
和传递容器组件来做到这一点。请注意,它并不总是有效的。所以是这样的:
public static void changeLaf(JFrame frame) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(frame);
}
此方法将当前的 LaF 更改为系统。
编辑:
JRadioMenuItem
通过演示更改 LaF :
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class LafDemo {
public static void changeLaf(JFrame frame, String laf) {
if (laf.equals("metal")) {
try {
UIManager.setLookAndFeel(UIManager
.getCrossPlatformLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
if (laf.equals("nimbus")) {
try {
UIManager
.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
if (laf.equals("system")) {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
SwingUtilities.updateComponentTreeUI(frame);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton btnDemo = new JButton("JButton");
JSpinner spnDemo = new JSpinner();
JComboBox<String> cmbDemo = new JComboBox<String>();
cmbDemo.addItem("One");
cmbDemo.addItem("Two");
cmbDemo.addItem("Three");
JMenuBar mBar = new JMenuBar();
frame.setJMenuBar(mBar);
JMenu mnuLaf = new JMenu("Look and feel");
JRadioButtonMenuItem mniNimbus = new JRadioButtonMenuItem(
"Nimbus");
JRadioButtonMenuItem mniMetal = new JRadioButtonMenuItem(
"Metal");
JRadioButtonMenuItem mniSystem = new JRadioButtonMenuItem(
"Systems");
ButtonGroup btnGroup = new ButtonGroup();
btnGroup.add(mniNimbus);
btnGroup.add(mniMetal);
btnGroup.add(mniSystem);
mBar.add(mnuLaf);
mnuLaf.add(mniNimbus);
mnuLaf.add(mniMetal);
mnuLaf.add(mniSystem);
mniNimbus.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
changeLaf(frame, "nimbus");
}
});
mniMetal.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
changeLaf(frame, "metal");
}
});
mniSystem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
changeLaf(frame, "system");
}
});
DefaultTableModel model = new DefaultTableModel(
new Object[][] {}, new String[] { "First", "Second" });
model.addRow(new Object[] { "Some text", "Another text" });
JTable table = new JTable(model);
panel.add(btnDemo);
panel.add(spnDemo);
panel.add(cmbDemo);
frame.add(panel, BorderLayout.NORTH);
frame.add(new JScrollPane(table), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
您只需要使用UIManager.LookAndFeelInfo[]
来存储 available LookAndFeel
,然后使用UIManager.setLookAndFeel(LookAndFeelClassName)
来设置并在此之后调用SwingUtilities.updateComponentTreeUI(frameReference)
pack
在最后调用JFrame/JWindow/JDialog
(父容器),正如Swing Lord
@AndrewThompson 所指定的那样。
请看一下这个小例子:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LookAndFeelDemo {
private JFrame frame;
private JButton button;
private int counter;
private Timer timer;
private JLabel lafNameLabel;
private UIManager.LookAndFeelInfo[] lafs;
public LookAndFeelDemo() {
lafs = UIManager.getInstalledLookAndFeels();
counter = 0;
}
private ActionListener eventActions = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == timer) {
counter %= lafs.length;
try {
UIManager.setLookAndFeel(lafs[counter].getClassName());
} catch(Exception e) {e.printStackTrace();}
SwingUtilities.updateComponentTreeUI(frame);
lafNameLabel.setText(lafs[counter++].getName());
frame.pack();
} else if (ae.getSource() == button) {
if (timer.isRunning()) {
timer.stop();
button.setText("Start");
} else {
timer.start();
button.setText("Stop");
}
}
}
};
private void displayGUI() {
frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
lafNameLabel = new JLabel("Nothing to display yet...", JLabel.CENTER);
button = new JButton("Stop");
button.addActionListener(eventActions);
contentPane.add(lafNameLabel);
contentPane.add(button);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
timer.stop();
}
});
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, eventActions);
timer.start();
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new LookAndFeelDemo().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
更新代码示例以包括动态LookAndFeels
添加JRadioButtonMenuItem
。虽然请注意,如果您使用Action而不是 an会更好ActionListener
,我使用它只是为了合并前面代码中的更改:-)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LookAndFeelDemo {
private JFrame frame;
private JButton button;
private int counter;
private Timer timer;
private JLabel lafNameLabel;
private ButtonGroup bg;
private JRadioButtonMenuItem[] radioItems;
private UIManager.LookAndFeelInfo[] lafs;
public LookAndFeelDemo() {
lafs = UIManager.getInstalledLookAndFeels();
counter = 0;
}
private ActionListener eventActions = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == timer) {
counter %= lafs.length;
try {
UIManager.setLookAndFeel(lafs[counter].getClassName());
} catch(Exception e) {e.printStackTrace();}
SwingUtilities.updateComponentTreeUI(frame);
lafNameLabel.setText(lafs[counter++].getName());
frame.pack();
} else if (ae.getSource() == button) {
if (timer.isRunning()) {
timer.stop();
button.setText("Start");
} else {
timer.start();
button.setText("Stop");
}
} else if (ae.getSource() instanceof JRadioButtonMenuItem) {
JRadioButtonMenuItem radioItem = (JRadioButtonMenuItem) ae.getSource();
String lafName = radioItem.getActionCommand();
System.out.println("LAF Name : " + lafName);
for (int i = 0; i < radioItems.length; i++) {
if (lafName.equals(radioItems[i].getActionCommand())) {
setApplicationLookAndFeel(lafs[i].getClassName());
}
}
}
}
private void setApplicationLookAndFeel(String className) {
try {
UIManager.setLookAndFeel(className);
} catch (Exception e) {e.printStackTrace();}
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
}
};
private void displayGUI() {
frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
lafNameLabel = new JLabel("Nothing to display yet...", JLabel.CENTER);
button = new JButton("Start");
button.addActionListener(eventActions);
contentPane.add(lafNameLabel);
contentPane.add(button);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
timer.stop();
}
});
frame.setJMenuBar(getMenuBar());
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, eventActions);
}
private JMenuBar getMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu lookAndFeelMenu = new JMenu("Look And Feels");
bg = new ButtonGroup();
radioItems = new JRadioButtonMenuItem[lafs.length];
for (int i = 0; i < radioItems.length; i++) {
radioItems[i] = new JRadioButtonMenuItem(lafs[i].getName());
radioItems[i].addActionListener(eventActions);
bg.add(radioItems[i]);
lookAndFeelMenu.add(radioItems[i]);
}
menuBar.add(lookAndFeelMenu);
return menuBar;
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new LookAndFeelDemo().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
好吧,考虑到当前选择了 Nimbus,我假设您想将 LAF 更改为 Nimbus?如果是这样,您将需要这样做:
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
如果要查看当前安装的所有 LAF,可以使用UIManager.getInstalledLookAndFeels();
. 有关更多信息,请考虑阅读此
这是我的:
当用户单击 JMenuItem 或您选择的其他内容时发生 Action 事件时,您应该调用此方法。
private void changeLookAndFeel() {
final LookAndFeelInfo[] list = UIManager.getInstalledLookAndFeels();
final List<String> lookAndFeelsDisplay = new ArrayList<>();
final List<String> lookAndFeelsRealNames = new ArrayList<>();
for (LookAndFeelInfo each : list) {
lookAndFeelsDisplay.add(each.getName());
lookAndFeelsRealNames.add(each.getClassName());
}
if (lookAndFeelsDisplay.size() != lookAndFeelsRealNames.size()) {
throw new InternalError();
}
String changeSpeed = (String) JOptionPane.showInputDialog(this, "Choose Look and Feel Here\n(these are all available on your system):", "Choose Look And Feel", JOptionPane.QUESTION_MESSAGE, null, lookAndFeelsDisplay.toArray(), null);
boolean update = false;
if (changeSpeed != null && changeSpeed.length() > 0) {
for (int a = 0; a < lookAndFeelsDisplay.size(); a++) {
if (changeSpeed.equals(lookAndFeelsDisplay.get(a))) {
try {
UIManager.setLookAndFeel(lookAndFeelsRealNames.get(a)); //re update with correct class name String
this.whichLookAndFeel = changeSpeed;
update = true;
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
err.println(ex);
ex.printStackTrace();
Logger.getLogger(Starfighter.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
if (update) {
int width = 800;
int height = 625;
if (UIManager.getLookAndFeel().getName().equals("CDE/Motif")) {
height += 12;
}
this.setSize(width, height);
this.menuBar.updateUI();
this.menuBar = new JMenuBar();
menuBar.updateUI();
this.setJMenuBar(menuBar);
}
}