# Java Notes

# Preferences

The `java.util.pref.Preferences` class, which was added in Java 1.4 to provide improved functionality over the `java.util.Properties` class, is used to store and get persistent (remains on disk between program executions) hierarchical name/values pairs. These preferences are stored in an operating system dependent manner, eg in the Windows registry or a Mac preferences file, but you don't have to be concerned with the actual way it is stored. Both system and user preferences can be obtained.

Privilege issues. I've heard that `Preferences` only works with "privileged" programs, so can't be used by unsigned WebStart or Applet programs. This seems like a very serious limitation, altho I can understand that you don't want unknown programs inserting things in your registry.

Package. The method of using Preferences described below gets a Preference object associated with the package of the current application, which effectively gives each program a unique set of preferences. Use of unique package names is therefore very important.

## Description

The following is a summary of common methods used to get top-level user preferences for a package. The `get...` methods take a String key and always require a default value, which will be returned if the key is not found. Assume.
`String key; String s; int i; boolean b; float f; double d; long l; byte[] ba; String[] allKeys;`

java.util.pref.Preferences - Used to maintain persistent key/value pairs.
prefs = | Preferences.userNodeForPackage(this.getClass());
|  | A new user Preferences object associated with this package.
Setting key values.
| prefs.put(key, s); | Associates s with String key
| prefs.putBoolean(key, b); | Associates b with String key
| prefs.putInt(key, i); | Associates i with String key
| prefs.putLong(key, l); | Associates l with String key
| prefs.putDouble(key, d); | Associates d with String key
| prefs.putFloat(key, f); | Associates f with String key
| prefs.putByteArray(key, ba); | Associates ba with String key
Getting key values.
s = | prefs.get(key, sdef); | Value associated with key or the default value sdef.
b = | prefs.getBoolean(key, bdef); | Value associated with key or the default value bdef.
i = | prefs.getInt(key, idef); | Value associated with key or the default value idef.
l = | prefs.getLong(key, ldef); | Value associated with key or the default value ldef.
d = | prefs.getDouble(key, ddef); | Value associated with key or the default value ddef.
f = | prefs.getFloat(key, fdef); | Value associated with key or the default value fdef.
ba = | prefs.getByteArray(key, badef); | Value associated with key or the default value badef.
Less common methods - These are used in the program below.
| prefs.clear(); | Clears all preferences.
allKeys = | prefs.keys(); | Returns String array of all keys.
| prefs.remove(key); | Removes value associated with string key.

## Example

The following program illustrates getting and saving user name/value pairs. Run the program, set some preferences, stop the program, and when you rerun the program you'll see the the preferences will be correctly retrieved from persistent storage!

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    /**
     * PrefTest.java - A simple program to show top-level user preferences.
     * 1. Run the program and set some preferences.
     * 2. Stop the program.
     * 3. Rerun the program, and you'll see that it restores the preferences!
     *
     * @version 2004-04-18 Rodenbach, minor changes 2006-02-11
     * @author Fred Swartz
    */

    package prefdemo;

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    import java.util.prefs.Preferences;
    import java.util.prefs.BackingStoreException;   //Note 1

    /////////////////////////////////////////////////////////////////// PrefTest
    class PrefTest extends JFrame {
        private JTextField _nameField = new JTextField(8);
        private JTextField _valueField= new JTextField(8);
        private JList      _prefList  = new JList(new String[] {});

        private Preferences _prefs;  // Holds the preferences from system.

        //========================================================== constructor
        /** Constructor for JFrame. */
        PrefTest() {
            _prefs = Preferences.userNodeForPackage(this.getClass());
            setListFromPrefs();

            //... Create and set attributes of widgets.
            JScrollPane scrollingList = new JScrollPane(_prefList);
            JButton newKeyButton      = new JButton("Put Key/Value");
            JButton clearButton       = new JButton("Clear All");
            JButton delSelectedButton = new JButton("Remove Selected");

            //... Set action listeners.
            newKeyButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if (_nameField.getText().length() > 0) {
                        _prefs.put(_nameField.getText(), _valueField.getText());
                        _nameField.setText("");   // Clear fields after saving.
                        _valueField.setText("");
                        setListFromPrefs();  // Update display
                    } else {
                        _nameField.setText("Key?");
                    }
                }});

            clearButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    try {
                        _prefs.clear();
                        setListFromPrefs();  // Update display
                    } catch (BackingStoreException ex) {
                        System.out.println(ex);
                    }
                }});

            delSelectedButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    String selection = (String)_prefList.getSelectedValue();
                    if (selection != null) {
                        String key = selection.substring(0, selection.indexOf("="));
                        _prefs.remove(key);  // Remove the selected key.
                        setListFromPrefs();  // Update display
                    }
                }});

            //... Subpanel for adding keys
            JPanel addPanel = new JPanel(new FlowLayout());
            addPanel.add(new JLabel("Key"));
            addPanel.add(_nameField);
            addPanel.add(new JLabel("Value"));
            addPanel.add(_valueField);
            addPanel.add(newKeyButton);

            //... Subpanel for removing keys
            JPanel removePanel = new JPanel(new FlowLayout());
            removePanel.add(delSelectedButton);
            removePanel.add(clearButton);

            //... Create a new content pane
            JPanel content = new JPanel(new BorderLayout());
            content.add(addPanel     , BorderLayout.NORTH);
            content.add(scrollingList, BorderLayout.CENTER);
            content.add(removePanel  , BorderLayout.SOUTH);

            //... Set the JFrame characteristics.
            this.setTitle(this.getClass().getName());
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setContentPane(content);
            this.pack();
        }//end constructor

        //===================================================== setListFromPrefs
        /** Get key value pairs from system, and display them. */
        private void setListFromPrefs() {
            try {
                String[] keys = _prefs.keys();    //Note 2
                for (int i=0; i<keys.length; i++) {
                    keys[i] += "=" + _prefs.get(keys[i], "ERROR");
                }
                _prefList.setListData(keys);
            } catch (BackingStoreException ex) {
                JOptionPane.showMessageDialog(null, "No initial preferences");
            }
        }

        //================================================================= main
        public static void main(String[] args) {
            JFrame window = new PrefTest();
            window.setVisible(true);
        }

    }

### Notes

1. Importing BackingStoreException is usually not necessary, but is used here because the (rarely needed) keys() method is called.
2. The keys() method is usually not called. Normally you will request the keys you are interested in explicitly.