Skip to main content

My Preferences

Posted by malenkov on June 5, 2009 at 5:05 AM PDT

The JavaFX 1.2 SDK provides many useful utility classes such as the Properties class used to access and store name/value pairs or the Storage class used to store the data locally on the client system.

So far the JavaFX programming language does not support hash tables to store data of any type, but you can always use the Properties class for this purpose. For a start, let's create methods to put and get numbers. For example,

  public function put(key: String, value: Number) {
    put(key, value.toString())
  }

  public function get(key: String, default: Number) {
    var value = get(key);
    if (value != null) try {
      return Number.valueOf(value)
    }
    catch (exception) {
    }
    default
  }

Note that the put method converts a number into a string and the get method tries to convert a string into a number. For primitive data types, this is done rather easily. For more complex cases, you can develop your own implementation of the Converter interface and use it to convert an object into a string and vice versa. Let it be your homework exercise.

Now add an ability to store properties automatically. I decided that at the moment of initialization, the class should read all properties from the storage and put them back when an application terminates. This task is very simple.

  var storage: Storage;

  postinit {
    storage = Storage {
      source: source
    }
    if (storage.resource.readable) {
      load(storage.resource.openInputStream())
    }
    FX.addShutdownAction(store)
  }

  function store() {
    if (storage.resource.writable) {
      store(storage.resource.openOutputStream(true))
    }
  }

Consider an example of how to use the Preferences class. Create a simple application that stores the position and size of a window. Launch this application. Move the window, resize it and then close the application. Launch the same application again. You see that the window is located where you left it in the previous session. It is convenient, isn't it?

class PersistentStage extends Stage {
  def preferences = Preferences {
    source: "bounds"
  } on replace {
    def s = Screen.primary.visualBounds;
    width  = preferences.get("W", s.width  / 2);
    height = preferences.get("H", s.height / 2);
    x = preferences.get("X", s.minX + (s.width  - width)  / 2);
    y = preferences.get("Y", s.minY + (s.height - height) / 2);
  }
  override var x      on replace {preferences.put("X", x     )}
  override var y      on replace {preferences.put("Y", y     )}
  override var width  on replace {preferences.put("W", width )}
  override var height on replace {preferences.put("H", height)}
}

Later I will improve the Application class from the previous post by adding a support for properties storage.

original post

Related Topics >>