在运行时更改 Java 应用程序的外观(IDE:Netbeans)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18418912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change the look and feel of java application on runtime (IDE: Netbeans)
提问by Rafi Abro
I am building a java app and I want to change the theme(look and feel) of application at runtime with these radio buttons. I do not know how to do this!
我正在构建一个 Java 应用程序,我想在运行时使用这些单选按钮更改应用程序的主题(外观)。我不知道该怎么做!
Thanks in advance!
提前致谢!
采纳答案by Branislav Lazic
You can do that by calling SwingUtilities.updateTreeComponentUI(frame)
and passing container component. Be aware that it won't be efficient always. So something like this:
您可以通过调用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);
}
This method changes current LaF to systems.
此方法将当前的 LaF 更改为系统。
EDIT:
编辑:
Changing LaF via JRadioMenuItem
demo:
通过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);
}
});
}
}
回答by Josh M
Well, considering Nimbus is currently selected, I am going to assume that you want to change the LAF to Nimbus? If so, you will need to do this:
好吧,考虑到当前选择了 Nimbus,我假设您想将 LAF 更改为 Nimbus?如果是这样,您将需要执行以下操作:
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
If you want to see all of the LAFs that are currently installed, you could use UIManager.getInstalledLookAndFeels();
. For more information, consider reading this
如果要查看当前安装的所有 LAF,可以使用UIManager.getInstalledLookAndFeels();
. 有关更多信息,请考虑阅读此内容
回答by nIcE cOw
You simply need to use the UIManager.LookAndFeelInfo[]
to store the available LookAndFeel
, then use UIManager.setLookAndFeel(LookAndFeelClassName)
to set and after this do call SwingUtilities.updateComponentTreeUI(frameReference)
您只需要使用UIManager.LookAndFeelInfo[]
来存储可用的LookAndFeel
,然后使用UIManager.setLookAndFeel(LookAndFeelClassName)
来设置并在此之后调用SwingUtilities.updateComponentTreeUI(frameReference)
EDIT :
编辑 :
Do call pack
on JFrame/JWindow/JDialog
(parent container) at the end, as very much specified by the Swing Lord
@AndrewThompson.
做电pack
在JFrame/JWindow/JDialog
末(父容器),因为很大程度上是由指定的Swing Lord
@AndrewThompson。
Please have a look at this small example :
请看一下这个小例子:
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);
}
}
EDIT 2 :
编辑 2:
Updating the code example to include adding LookAndFeels
from JRadioButtonMenuItem
on the fly. Though please, be advised, it would be much better if you use Actioninstead of an ActionListener
, I used it only to incorporate the changes in the previous code :-)
更新所述代码示例包括添加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);
}
}
回答by TheArchon
Here's mine:
这是我的:
You should call this method when a Action event occurs when the user clicks on a JMenuItem or something else of your choice.
当用户单击 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);
}
}