How do I keep the Look And Feel selected in the JComboBox after the window is closed?

3

I just created a simple JFrame in NeatBeans with some Look And Feel's (LAF) available, using a JComboBox so that the user chooses the LAF you want, and I also put the "Save" button for Action

I can change the "Theme" perfectly. The problem is that the chosen LAF is only applied at that very moment of execution, when I close and execute the JFrame again, the LAF chosen does not remain saved.

I would like to know how to create a method for the selected LAF to be applied when reopening JFrame .

Here is the example:

HereistheSaveButtonCode:

privatevoidbtnSalvarActionPerformed(java.awt.event.ActionEventevt){//AcaodeBotaoSalvarStringt=(String)jComboBoxLAF.getSelectedItem();JOptionPane.showMessageDialog(null,t);try{if("Metal".equals(t)){

                UIManager.setLookAndFeel(new MetalLookAndFeel());
                this.setVisible(false);
                new TelaJtable().setVisible(true);

            }else if("Nimbus".equals(t)){
                UIManager.setLookAndFeel(new NimbusLookAndFeel());
                this.setVisible(false);
                new TelaJtable().setVisible(true);

            }else if("CDE/Motif".equals(t)){
                UIManager.setLookAndFeel(new MotifLookAndFeel());
                this.setVisible(false);
                new TelaJtable().setVisible(true);

            }else if("Windows".equals(t)){
                UIManager.setLookAndFeel(new WindowsLookAndFeel());
                this.setVisible(false);
                new TelaJtable().setVisible(true);
            }
            else if("Windows Classic".equals(t)){
                UIManager.setLookAndFeel(new WindowsClassicLookAndFeel());
                this.setVisible(false);
                new TelaJtable().setVisible(true);
            }

        } catch (Exception e) {

        }            
    }                                         
    
asked by anonymous 31.08.2016 / 03:43

1 answer

3

You can do this with a simple text file, saving the LAF¹ name (or the entire class name) when you change LAF¹ within the application, and loading this file when you open the application to check which theme was saved.

One of the ways I always use it when I need this kind of feature is to use the Properties , where I can save multiple configuration items and retrieve them more easily than doing this by reading a traditional text file.

For your case, I've done an example class called Propriedade , whose function is to read and save the LookAndFeel of your application from a config.properties file. The latter you can change by any name (eg config.txt).

public static class Propriedade {

    private static Properties prop;
    //aqui você pode mudar o nome e a extensão do arquivo
    private static String path = "config.properties";

    private static void LoadPropertiesFile() throws IOException {
        prop = new Properties();
        File f = new File(path);

        if (f.isFile()) {
            FileInputStream file = new FileInputStream(f);
            prop.load(file);
        } else {
            //se o arquivo não existir, cria um novo
            f.createNewFile();
            FileInputStream file = new FileInputStream(f);
            prop.load(file);
            //seta um valor inicial em branco pro parametro do LAF
            // isso é para evitar NullPointerException ao chamar
            // getLookAndFeel() logo após criar o arquivo
            setLookAndFeel("");
        }
    }

    public static String getLookAndFeel() throws IOException {
        LoadPropertiesFile();
        return prop.getProperty("lookandfeel.name");
    }

    public static void setLookAndFeel(String name) throws IOException {
        LoadPropertiesFile();
        prop.setProperty("lookandfeel.name", name);
        prop.store(new FileOutputStream(path), "");
    }
}

To use, you only need to invoke one of the two public methods (the class is already creating the file if it does not exist).

Just remember that if you call getLookAndFeel() before opening your screen, it's important to check if the returned value is null or blank, because if the class just created the file, the returned value will be blank (as can be seen in the LoadPropertiesFile() method), or if someone changes the values directly in the file, it can return null as well.

  

Note: As stated in the comments, this method will only work correctly with the look and feel's that are installed, if you are using some external to the java, you need to install them using the UIManagerr.installLookAndFeel(String name, String className) method, where name is a "friendly" LAF¹ name, and className is the name of the class, it would look something like this: installLookAndFeel(String "Custom LAF¹", String "com.example.mycustomlaf") .

For an example, see an executable example of how this class works:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import java.util.Properties;

/**
 *
 * @author diego.felipe
 */
public class SaveLAFTest {

    private void start() {
        final JFrame frame = new JFrame();
        frame.setTitle("Frame principal");
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JComboBox comboLAF = new JComboBox();

        for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            comboLAF.addItem(info.getName());
        }

        comboLAF.addItemListener(e -> {

            if (e.getStateChange() == ItemEvent.SELECTED) {
                String LAFSelected = (String) e.getItem();
                changeLookAndFeel(LAFSelected);
                SwingUtilities.updateComponentTreeUI(frame);
            }

        });

        frame.setLayout(new FlowLayout());
        frame.add(comboLAF);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
    }

    private void changeLookAndFeel(String name) {
        for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if (info.getName().equalsIgnoreCase(name)) {
                try {
                    UIManager.setLookAndFeel(info.getClassName());
                    Propriedade.setLookAndFeel(name);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {

        try {
            String myLAF = Propriedade.getLookAndFeel();
            if (myLAF == null || myLAF.isEmpty()) {
                Propriedade.setLookAndFeel(UIManager.getLookAndFeel().getName());
            } else {

                for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                    if (myLAF.equalsIgnoreCase(info.getName())) {
                        UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        EventQueue.invokeLater(() -> new SaveLAFTest().start());
    }

    public static class Propriedade {

        private static Properties prop;
        private static String path = "config.properties";

        private static void LoadPropertiesFile() throws IOException {
            prop = new Properties();
            File f = new File(path);

            if (f.isFile()) {
                FileInputStream file = new FileInputStream(f);
                prop.load(file);
            } else {
                f.createNewFile();
                FileInputStream file = new FileInputStream(f);
                prop.load(file);
                setLookAndFeel("");
            }
        }

        public static String getLookAndFeel() throws IOException {
            LoadPropertiesFile();
            //lookandfeel.name é o nome que será salvo do parâmetro
            //você pode mudar pra outro, mas lembre de alterar também
            // no método setLookAndFeel()
            return prop.getProperty("lookandfeel.name");
        }

        public static void setLookAndFeel(String name) throws IOException {
            LoadPropertiesFile();
            prop.setProperty("lookandfeel.name", name);
            prop.store(new FileOutputStream(path), "");
        }
    }
}

See working in the gif below:

1 - LAF = look and feel

    
31.08.2016 / 13:59