Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing platform-specific application data area

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?

like image 714
Sturm Avatar asked Oct 31 '22 16:10

Sturm


1 Answers

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

Edit

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:

enter image description here

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.

like image 62
dic19 Avatar answered Nov 11 '22 06:11

dic19