Change the look and feel of java application on runtime (IDE: Netbeans)

11,625

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

Share:
11,625
Rafi Abro
Author by

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, 2022

Comments

  • Rafi Abro
    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!

    Java Application Changing Look and feel

    Thanks in advance!

  • nIcE cOw
    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 the JButton which was doing nothing before :-) But atleast now, it will stop no matter what happens :-)
  • Andrew Thompson
    Andrew Thompson over 10 years
    A call to pack() after PLAF change might also be appropriate. The Nested Layout Example leaves the choice to the user.
  • nIcE cOw
    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 selecting pack() :( It did accommodated the new effects a bit more nicely after calling pack() :-)
  • Andrew Thompson
    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
    Rafi Abro over 10 years
    I 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
    Rafi Abro over 10 years
    I 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
    Rafi Abro over 10 years
    Thanks 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 passes frame to method changeLaf(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
    Branislav Lazic over 10 years
    @RafiAbro You mean you extended your class with JFrame? I don't understand.
  • Branislav Lazic
    Branislav Lazic over 10 years
    @RafiAbro Then just pass this keyword instead of frame.
  • Rafi Abro
    Rafi Abro over 10 years
    I tried this keyword but it shows error that non static variable can not be referenced in a static method..!
  • Branislav Lazic
    Branislav Lazic over 10 years
    @RafiAbro Then make changeLaf method as non-static. Just: public void changeLaf(JFrame frame, String laf) {....}
  • Rafi Abro
    Rafi Abro over 10 years
  • Rafi Abro
    Rafi Abro over 10 years
    Its 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
    mKorbel over 10 years
    @nIcE cOw who knows :-) my hat down, glad and welcome here