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

Asked

Viewed 335 times

3

I just created a simple JFrame no Neatbeans with some Look And Feel’s(LAF) available, using a JComboBox for the user to choose 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 exact moment of execution, when I close and execute the JFrame again, the chosen LAF does not remain saved.

I would like to know how to create some Method for the selected LAF to remain applied when reopening the JFrame.

Here is the Example:

inserir a descrição da imagem aqui

Here is the Save Button Code:

private void btnSalvarActionPerformed(java.awt.event.ActionEvent evt) {                                          
        // Acao de Botao Salvar
       String t = (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) {

        }            
    }                                         
  • Are you saving it in an external file? This is the only way to do it. using the netbeans GUI builder, the initial theme will always be Nimbus, unless you create a mechanism to save the chosen option to an external file, and check it before the screen opens.

  • Ola diegofm thanks for your reply, I’m sorry maybe it’s my explanation poorly explained, not in the external file, I want to save the option of LAF/ Selected theme of type when running Jframe again switch to another LAF chosen earlier, so you don’t have to always select the LAF every time you run Jframe! since the "save" button action I created only changes the LAF to another, but the option is not saved, I have to select every time.

  • 1

    That’s what I said. After terminating the program, it is dumped from memory, nothing is saved (if you have not programmed any kind of data persistence). You have to define a default theme that will always be used when opening (as netbeans already does with Nimbus), that’s all. Any change of this, need external file.

  • Thanks again diegofm, Opa I have no idea how to do this, can you give me an orientation to be able to save in an external file?

1 answer

3


You can do this with a simple text file, saving the LAF name¹(or the name of the entire class) when changing the LAF¹ inside the application, and loading this file when opening the application to check which theme was saved.

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

For your case, I made an example of class called Propriedade, whose function is to read and save Lookandfeel from your file application config.properties. The latter you can exchange for any name(e.g. 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 remembering that if you call the getLookAndFeel() before opening your screen, it is important to check whether the returned value is null or blank, because if the class has just created the file, the returned value will be blank (as can be seen in the methodLoadPropertiesFile()), or if someone changes the values directly in the file, it can return null as well.

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


For 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 on gif below:

inserir a descrição da imagem aqui


1 - LAF = look and Feel

  • Hello diegofm you helped me a lot, everything worked out, but I could not express any feeling of gratitude as the rule does not allow us if I am not mistaken. but I accepted your answer as helpful. But I have one more problem here, I would like one more help from you, I have an extra Lafs library, how can I add the extra Lafs next to the Lafs available in the code you created for me?

  • Nome da Biblioteca: JTattoo-1.6.11.jar

Aqui estão os nomes de pacotes e Classes:
UIManager.setLookAndFeel("com.jtatoo.plaf.noire.NoireLookAndFeel");
UIManager.setLookAndFeel("com.jtattoo.plaf.acryl.AcrylLookAndFeel");
UIManager.setLookAndFeel("com.jtattoo.plaf.texture.TextureLookAndFeel");
UIManager.setLookAndFeel("com.jtattoo.plaf.smart.SmartLookAndFeel");

  • Eu tentei adicionar da seguinte forma no teu código lá no initComponents(); 
 for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
 comboLAF.addItem(info.getName());
 }
//assim comboLAF.addItem(new NoireLookAndFeel()); //asimm comboLAF.addItem(new info("Noirelookandfeel", Noirelookandfeel.class.getName()); &#Xa?

  • 1

    @Américojorge I believe you need to install the LAFS, using the command installLookAndFeel(String name, String className), passing the 'friendly name you want to be called the LAF, and the address of your class (the one you are trying to pass in the code). This needs to be done with all the Lafs Customs there at the beginning of try, then all will be listed normally in the combobox.

  • 1

    you are a real professional here, it went all right! a strong hug , ate more..

Browser other questions tagged

You are not signed in. Login or sign up in order to post.