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:
1 - LAF = look and Feel
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.
– user28595
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.
– Américo Jorge
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.
– user28595
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?
– Américo Jorge