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