In Java, I need to find a way to store some data locally so that it is available between reboots. Simple things, such as window location/size. I know that such information is usually stored in C:\Users\<username>\AppData
on Windows (accessed by typing %APPDATA%
in the address bar of Windows Explorer), but I have no idea where it is stored on Mac OS X. (As a side note, I still don't understand the structure of that %APPDATA%
folder on Windows, with its \Roaming
, \Local
, \LocalLow
, etc. subfolders.)
Surely there is some way for information like window location to be stored in these areas depending on the OS. Perhaps there is even an library already pre-built for doing these relatively ubiquitous tasks?
In Java, I need to find a way to store some data locally so that it is available between reboots. Simple things, such as window location/size.
I think Preferences API suits this requirement. In a nutshell:
Applications require preference and configuration data to adapt to the needs of different users and environments. The
java.util.prefs
package provides a way for applications to store and retrieve user and system preference and configuration data. The data is stored persistently in an implementation-dependent backing store. There are two separate trees of preference nodes, one for user preferences and one for system preferences.
There is a short yet useful tutorial here. And here is a little example based on your requirements:
import java.util.prefs.Preferences;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class SwingPreferencesTest {
private void createAndShowGUI() {
JTextField dummyTextField = new JTextField(20);
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(dummyTextField);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
Preferences prefs = Preferences.userRoot().node(this.getClass().getName());
// Define default values here
System.out.println("width: " + prefs.getDouble("width", 100d));
System.out.println("height: " + prefs.getDouble("height", 100d));
System.out.println("x: " + prefs.getDouble("x", 0d));
System.out.println("y: " + prefs.getDouble("y", 0d));
// Set new values here
prefs.putDouble("width", frame.getPreferredSize().getWidth());
prefs.putDouble("height", frame.getPreferredSize().getHeight());
prefs.putDouble("x", frame.getLocationOnScreen().getX());
prefs.putDouble("y", frame.getLocationOnScreen().getY());
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SwingPreferencesTest().createAndShowGUI();
}
});
}
}
If you run it the first time you'll see the preferences default values in console:
width: 100.0
height: 100.0
x: 0.0
y: 0.0
If you run it again then these values are updated. In my case:
width: 240.0
height: 59.0
x: 130.0
y: 130.0
As per @Puce comment below, on Windows data is stored in the registry and it makes sense because it's the way that Windows uses to store user/system/software data. You can find the registry entry generated in the example under HKEY_CURRENT_USER\JavaSoft\Prefs\[package\class name]
as shown in picture below:
Note: tested on Windows 8 x64, JDK 1.7
If you don't want to fill the registry with these preferences, then you can just store a path to your application folder (as other applications do) and use this path to load config data from plain properties files. The main advantage to keep using Preferences (at least to store the application's path) is the mechanism to retrieve/store config data is designed to be cross-platform and JVM implementers (not developers) are who have to deal with the actual implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With