Adding a listener to a preferences tree

You can implement the NodeChangeListener to listen for events when nodes are added or removed and implement the PreferenceChangeListener to listen for events that are emitted when the value of the preference changes. You need to add a listener to that particular node in which you are interested.

The first example I wrote involved 2 VMs. The first app showed a Swing gui and listened to preference change events, while the other app changed the preferences. Events were not received by the first app. It turns out that event notification is only guaranteed for changes made in the same VM.

This example starts up, writes a couple preferences, fires up a thread that changes these preferences after 5 seconds. You should see the changes in the GUI.

com/esus/examples/preferences/Main.java:

package com.esus.examples.preferences;

import javax.swing.border.*;
import java.util.prefs.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame 
{
   Preferences preferences;
 
   public static final String APPLICATIONPATH = "applicationpath";
   public static final String USERFONT        = "userfont";
   public static final String LASTUSERLOGIN   = "lastuserlogin";
   public static final String LDAPURL         = "ldapurl";
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      loadPreferences();
 
      JLabel appPathLabel       = new JLabel("Application Path:");
      JLabel userFontLabel      = new JLabel("User font:");
      JLabel lastUserLoginLabel = new JLabel("Last user logged in: ");
      JLabel ldapURLLabel       = new JLabel("LDAP url:");
      final JTextField appPathTf       = new JTextField(
                                  preferences.get(APPLICATIONPATH, ""));
      final JTextField userFontTf      = new JTextField(
                                  preferences.get(USERFONT, ""));
      final JTextField lastUserLoginTf = new JTextField(
                                  preferences.get(LASTUSERLOGIN, ""));
      final JTextField ldapURLTf       = new JTextField(
                                  preferences.get(LDAPURL, ""));
 
      JPanel prefsPanel = new JPanel();
      prefsPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
      prefsPanel.setLayout(new GridLayout(4, 4, 10, 10));
      prefsPanel.add(appPathLabel);
      prefsPanel.add(appPathTf);
      prefsPanel.add(userFontLabel);
      prefsPanel.add(userFontTf);
      prefsPanel.add(lastUserLoginLabel);
      prefsPanel.add(lastUserLoginTf);
      prefsPanel.add(ldapURLLabel);
      prefsPanel.add(ldapURLTf);
 
      JPanel buttonPanel = new JPanel();
      buttonPanel.setLayout(new GridLayout(1, 2, 70, 70));
 
      JButton cancelButton = new JButton("Cancel");
      cancelButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            System.exit(0);
         }
      });
 
      JButton saveButton = new JButton("Save");
      saveButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            preferences.put(APPLICATIONPATH, appPathTf.getText());
            preferences.put(USERFONT,        userFontTf.getText());
            preferences.put(LASTUSERLOGIN,   lastUserLoginTf.getText());
            preferences.put(LDAPURL,         ldapURLTf.getText());
            System.out.println("Preferences saved!");
         }
      });

      // listen for changes to my preferences
      preferences.addPreferenceChangeListener(new PreferenceChangeListener() {
         public void preferenceChange(PreferenceChangeEvent pce) {
            String key = pce.getKey();
            String value = pce.getNewValue();
            if (key.equals(APPLICATIONPATH))    appPathTf.setText(value);
            else if (key.equals(USERFONT))      userFontTf.setText(value);
            else if (key.equals(LASTUSERLOGIN)) lastUserLoginTf.setText(value);
            else if (key.equals(LDAPURL))       ldapURLTf.setText(value);
         }
      });
  
      buttonPanel.add(cancelButton);
      buttonPanel.add(saveButton);
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.CENTER, prefsPanel);
      getContentPane().add(BorderLayout.SOUTH, buttonPanel);
   }
 
   public void loadPreferences() {
      preferences = Preferences.userNodeForPackage(this.getClass());
 
      // put in some default values
      preferences.put(APPLICATIONPATH, "c:\application");
      preferences.put(USERFONT,        "Courier New");
      preferences.put(LASTUSERLOGIN,   "Joris Van den Bogaert");
      preferences.put(LDAPURL,         "ldap://localhost:389");
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(350, 190);
      main.setVisible(true);
 
      main.new ChangePreference().start();
   }
 
   class ChangePreference extends Thread {
      public void run() {
         try {
            Thread.sleep(5000);
         }
         catch(InterruptedException e) { }
 
         preferences.put(APPLICATIONPATH, "/home/me/test");
         preferences.put(USERFONT,        "Arial");
         preferences.put(LASTUSERLOGIN,   "Alicia Kolesnikova");
         preferences.put(LDAPURL,         "ldap://111.222.333.444:389");
      }
   }
}