Change the look and feel of java application on runtime (IDE: Netbeans)
Solution 1
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:
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.
EDIT:
Changing LaF via JRadioMenuItem
demo:
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);
}
});
}
}
Solution 2
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)
EDIT :
Do call pack
on JFrame/JWindow/JDialog
(parent container) at the end, as very much specified by the 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 :
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 Action instead of an ActionListener
, I used it only to incorporate the changes in the previous code :-)
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);
}
}
Solution 3
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:
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
Rafi Abro
The first thing you must know about me is that I always stand what I stand for. Good? The second thing you must know about yourself listening to me is that words are tricky. So when you know what me a stand for, when me explain a thing to you, you must never try to look 'pon it in a different way from what me a stand for. I am Me. In all the world, there is no one else exactly like me. Everything that comes out of me is authentically mine, because I alone chose it -- I own everything about me: my body, my feelings, my mouth, my voice, all my actions, whether they be to others or myself. I own my fantasies, my dreams, my hopes, my fears. I own my triumphs and successes, all my failures and mistakes. Because I own all of me, I can become intimately acquainted with me. By so doing, I can love me and be friendly with all my parts. I know there are aspects about myself that puzzle me, and other aspects that I do not know -- but as long as I am friendly and loving to myself, I can courageously and hopefully look for solutions to the puzzles and ways to find out more about me. However I look and sound, whatever I say and do, and whatever I think and feel at a given moment in time is authentically me. If later some parts of how I looked, sounded, thought, and felt turn out to be unfitting, I can discard that which is unfitting, keep the rest, and invent something new for that which I discarded. I can see, hear, feel, think, say, and do. I have the tools to survive, to be close to others, to be productive, and to make sense and order out of the world of people and things outside of me. I own me, and therefore, I can engineer me. I am me, and I am Okay. I believe the single most significant decision I can make on a day-to-day basis is my choice of attitude. It is more important than my past, my education, my bankroll, my successes or failures, fame or pain, what other people think of me or say about me, my circumstances, or my position. Attitude keeps me going or cripples my progress. It alone fuels my fire or assaults my hope. When my attitudes are right, there is no barrier too high, no valley too deep, no dream too extreme, no challenge too great for me. What probably confuses people is they know a lot about me, but it quite pleases me that there's more they don't know.
Updated on June 13, 2022Comments
-
Rafi Abro almost 2 years
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!
Thanks in advance!
-
nIcE cOw over 10 years@brano88 : THANK YOU for the edit :-) I just don't like
Anonymous Inner Classes
that is why I kept it that way, and added the functionality to theJButton
which was doing nothing before :-) But atleast now, it will stop no matter what happens :-) -
Andrew Thompson over 10 yearsA call to
pack()
after PLAF change might also be appropriate. The Nested Layout Example leaves the choice to the user. -
nIcE cOw over 10 years@AndrewThompson : Ahha, something new for me to learn on the topic :-) Thankyou for sharing and KEEP SMILING :-) Never looked at that
JCheckBox
for selectingpack()
:( It did accommodated the new effects a bit more nicely after callingpack()
:-) -
Andrew Thompson over 10 years@nIcEcOw I mainly put it there to help underline the fact that 'null layouts' can fail due to the end user (or their JRE) forcing another PLAF than the programmer intended. OTOH 'null layouts' can fail when the direction of the breeze changes, so I'm not sure my point was well made. ;)
-
Rafi Abro over 10 yearsI just want to change look and feel through a radio button. suppose:
if(JRadioButton1.isSelected()){ //then change the look and feel }else if(JRadioButton2.isSelected()){ //then change the other look and feel }
and as so on.. how can i do that..? -
Rafi Abro over 10 yearsI just want to change look and feel through a radio button. suppose:
if(JRadioButton1.isSelected()){ //then change the look and feel }else if(JRadioButton2.isSelected()){ //then change the other look and feel }
and as so on.. how can i do that..? -
Rafi Abro over 10 yearsThanks dear! its working quite fine! but I have another problem with that! which is that you are creating a frame by
JFrame frame = new JFrame();
and passesframe
to methodchangeLaf(frame, string)
But I have created a JFrame Form in my project and I want to pass that JFrame form in that method, I don't know how to do that! -
Branislav Lazic over 10 years@RafiAbro You mean you extended your class with
JFrame
? I don't understand. -
Branislav Lazic over 10 years@RafiAbro Then just pass
this
keyword instead offrame
. -
Rafi Abro over 10 yearsI tried this keyword but it shows error that non static variable can not be referenced in a static method..!
-
Branislav Lazic over 10 years@RafiAbro Then make
changeLaf
method as non-static. Just:public void changeLaf(JFrame frame, String laf) {....}
-
Rafi Abro over 10 years
-
Rafi Abro over 10 yearsIts giving same error that non static variable can not be referenced in a static method even I am removing static from a method changeLaf!
-
mKorbel over 10 years@nIcE cOw who knows :-) my hat down, glad and welcome here