Howto: Doing some storage in JavaFX
Friday, May 21, 2010 5:39:57 PM
I'm not an expert in code design or design patterns at all, but nonetheless I want to share my work with the hope that people which are new to JavaFX will find it helpful and that I'll get some feedback when I've designed it badly.
So why do I use the JavaFX Storage API? For me it's pretty clear: For signed applications it provides a huge lot of storage (as far as I remember over 80 MiB), it provides still some storage for unsigned ones, and it's platform independent, which means it will work without changes on a TV or a mobile. The second reason is that the files get removed, too, if the user decides to uninstall the application. This can be a problem in some situations. But I'll give my users the possibility to save their settings "in the cloud" anyway.
For my storage implementation, I used key/value pairs which get stored in one file per class. The files are by "convention" named as "package.class.param1.param2" (add more params if you like to).
I then made three .fx-Files, two of them simply holding data:
- Store.fx which manages the storage itself trought the storage API
- Setting.fx a class which simply holds a key/value-pair
- SettingsContainer.fx a class which holds all Setting-classes of one class and provides functions (well, as of now, only one) to access (and later maybe write) the settings stored inside and direct access to the Setting-classes.
Well, let's start with the simplest part: The Setting.fx:
public class Setting {
public var key:String;
public var value:String;
}
I think that's pretty obvious. Now we have the SettingsContainer.fx which manages the setting-classes:
public class SettingsContainer {
public var settings:Setting[];
public function getSettingValue(key:String):String {
var value:String;
for(setting in settings) {
if(setting.key == key) {
value = setting.value;
}
}
return value;
}
}
Now, as we have the data-holding classes, we get to the Store.fx which is - surprise! - not a class but simply a script file, because it doesn't make sense to have multiple instances of it:
public function store(component:String, settings:SettingsContainer):Void {
var store = Storage {
source: "{component}"
}
var writer = new BufferedWriter(new OutputStreamWriter(store.resource.openOutputStream(true)));
for(setting in settings.settings) {
writer.write("{setting.key}~{setting.value}");
writer.newLine();
}
writer.close();
}
public function load(component:String):SettingsContainer {
var store = Storage {
source: "{component}"
}
var reader = new BufferedReader(new InputStreamReader(store.resource.openInputStream()));
var line:String;
var ret = SettingsContainer{};
while((line = reader.readLine()) != null) {
var lineSplit = line.split("~");
insert Setting {
key: lineSplit[0]
value: lineSplit[1]
} into ret.settings;
}
return ret;
}
As you can read out of the code, the "library" unfortunately isn't capable of being used in the JavaFX Mobile runtime, because it uses the String.split() method. I have to figure out how to replace this functionality (with the substring method if it's available, or by writing the key and value on different lines), but as of now it's ok. There aren't any JavaFX-capable phones, anyway.








Anonymous # Monday, May 24, 2010 1:12:23 PM
Anonymous # Wednesday, May 26, 2010 4:05:47 PM
Anonymous # Wednesday, May 26, 2010 6:59:27 PM
Anonymous # Wednesday, May 26, 2010 7:01:07 PM
Anonymous # Wednesday, June 2, 2010 3:48:58 AM