Sir, what is your preference?
Tutorial Details:
Sir, what is your preference?
Sir, what is your preference?
By: By Ray Djajadinata
Manage your application's preferences with J2SE 1.4's new Preferences API
lmost all but the smallest applications have preferences -- a set of values that affect how the application behaves at runtime. Preferences examples range from configuring an MP3 player to sport a skin of your choice, to setting a 3D shooter game's to varying screen resolutions. Now, of course you want the values to be there next time you run the application, so usually they're made persistent, be it in a file, database, or some other storage mechanism.
As an application developer, how and where you put the preferences vary depending on your application, the platform it runs on, and the programming language. If your application will run only on Windows, then Registry is the place to put the preferences. Developers writing applications written in portable C/C++, on the other hand, usually put their preferences in files. Bigger, server-side applications might store them in a database (although usually something needs to be stored in a file -- the connection string to the database, for example).
Therefore, when designing your application, you'll always face the same preference management questions: Where do we store them? How? Is maintaining them easy enough? Can we easily move them to another platform when necessary? If Java is your programming language, you can follow several approaches in answering these questions. I'll compare the traditional approaches, then discuss in detail the latest option -- J2SE (Java 2, Standard Edition) 1.4's new Preferences API. Enjoy!
The old, simple, and unscalable approach
Ahhh -- good old Properties . It has been around since Java's beginning, JDK 1.0 to be exact. It's easy to use: just put the preferences into the Properties object and store them in a file. Later, when you need to get them back, load it from the file, and voila, you have a Properties object containing the values you previously stored in the file. It's as simple as that. What could possibly be wrong with this approach?
The problems with Properties
For simple applications with just a few preferences, java.util.Properties works just fine. However, as the application grows in size, with the Properties API you can develop problems such as:
Numerous property files, each assigned to a part of the application (usually, but not always, a package), forcing you to hardcode a gaggle of file names -- or even their paths -- inside your code
Several large property files, which force you to prevent name collisions and to track numerous different preferences
To solve the second problem, you'd typically create your own hierarchy out of the flat namespace. That is, you'd create names like:
myapp.payment.SSLPort=10256
myapp.payment.SETPort=10257
myapp.admin.listenPort=10258
Of course, the Properties API possesses no awareness of this hierarchy, so you'd have to add your own code on top of it. However, this approach also proves unsafe: if someone hand-edits the file and replaces a period with a comma in one of the names above, who knows what will happen to your application?
In other words, managing and maintaining preferences using the Properties API can quickly become a nightmare -- it simply doesn't scale! Besides, using the Properties API this way won't work with a platform without a local disk. Now let's take a look at another approach that solves most of these problems.
The powerful, back-end neutral, and (too) complex approach
In the second approach, you store preferences in a directory service through the JNDI (Java Naming Directory Interface) API, thus solving most problems that Properties presents. JNDI-stored preferences, however, generally proves too complex for our purposes. Not all applications designers want anything to do with a directory service; most just need a simple yet elegant way to store preferences.
Besides, you still don't know where exactly in the namespace you should store the preference data. Ideally, you don't want to know where; you just want a place to stuff the data in and get them out when needed!
The new, improved, yet simple approach!
The Preferences API solves problems the two approaches above cause, while keeping the interface simple. The whole package comprises only three interfaces, four classes, and two exceptions. Even better, most of the time, you need care about only one class: Preferences . (Other classes are more relevant to the API's implementers than its users .)
Because the Preferences API is back-end neutral, you need not care whether the data are stored in files, database tables, or a platform-specific storage such as the Windows Registry. In fact, you don't want to care, because the situation may differ across varying platforms, or even across implementations on the same platform.
The Preferences API also offers a simple way to organize your preferences hierarchically and to associate a package with a node. Both prove convenient because organizing your preferences becomes a no-brainer: a set of preferences for a module becomes associated with the respective package, that's it. You don't have to think, "Oh, let's see, for this module, they have to go to this file, and that module, that file, or is it this file? What's the convention again?"
I once enthusiastically told a colleague about the Preferences API, quite sure that he'd be impressed. Expressionless, he listened to me for a while, then asked:
Do you always have to go through the API to access the preferences? We move preferences from platform to platform during testing, and copying the property files over has worked well so far.
Well, I learned two things from his remark: first, impressing colleagues is not easy. Second, the Preferences API does offer an easy solution to his problem. That is, you can export the whole preferences tree, or just a node to XML format. Copy this file to the other machine, import it back, and you don't have to reset all the preferences from scratch!
Some basic concepts
By now you know that with the Preferences API you can organize your preferences in a hierarchical manner. Not only that, it also recognizes that some preferences are shared among users, while some are not.
Trees, trees everywhere
In the Preferences API, you manage preferences in tree-like collections of nodes, which act similarly to directories in a hierarchical file system. The name-value pairs under the nodes, in turn, act roughly similar to files under the directories.
Moreover, you traverse a preference tree similarly to the way you'd traverse a directory tree. At the top of a tree resides a root node with an absolute path name of "/" . Accordingly, a node named A under this root node has an absolute path name of "/A" , and a node named B under A "/A/B" , and so on.
System and user preference trees
The Preferences API recognizes two kinds of preference tree: one shared by all users of the system (that is, the system preference tree), and another specific to a particular user (the user preference tree). The notion of "system" and "user," however, can vary across implementations. For more details, read the sidebar, " Platform Differences ."
Put it into use
OK, enough talk about concepts. How do you use the API? The following sections show you how!
Obtain a Preferences object
Of course, before everything else, you have to obtain a Preferences object to work with. Unlike Properties , Preferences doesn't have any accessible constructor. Instead, you obtain the object through one of four static factory methods:
public static Preferences systemNodeForPackage(Object o) : Returns a node in the system preferences tree corresponding to the passed object's package
public static Preferences userNodeForPackage(Object o) : Returns a node in the user preferences tree corresponding to the passed object's package
public static Preferences systemRoot() : Returns the root of the system preferences tree
public static Preferences userRoot() : Returns the root of the user preferences tree
In the list above, the first two methods serve as convenience methods. Let's say you have class C in package P . Passing an instance of C to either of them will return (and if necessary, create) a node whose path corresponds to package P . So, even if the package name changes for some reason, there's no need to change your code. Listing 1 illustrates this point further:
Listing 1. Payer.java
package com.acme.myapp.user;
import java.util.prefs.Preferences;
public class Payer {
private static final String PREFERRED_CHANNEL =
"PreferredChannel";
private PreferredChannel preferredChannel =
PreferredChannel.WML;
public void storePreferences() {
Preferences prefs = Preferences.userNodeForPackage(this);
prefs.put(PREFERRED_CHANNEL, preferredChannel.toString());
// The rest of the code here...
}
public static void main(String[] args) {
// The test code
new Payer().storePreferences();
}
}
You'll see the result of running the code above under J2SE Beta 1.4 for Windows in Figure 1. Note that WML is encoded as /W/M/L , and PreferredChannel as /Preferred/Channel because Preferences has case-sensitive keys and node-names, while the backing store of choice (in this case Windows Registry) does not.
Figure 1. A call to userNodeForPackage() creates a node
under the user preferences root, with a path that corresponds to the package
The last two factory methods -- systemRoot() and userRoot() -- simply return the system root and the user root, respectively. This might be useful when you don't have any instance to pass in (in static methods, for example), or when you need to create paths manually (that is, independent of the package where the code resides). However, systemRoot() and userRoot() merely return the root nodes. To create and traverse down the branches of the preference tree, you need another method:
public abstract Preferences node(String pathName)
node()
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Sir, what is your preference?
View Tutorial: Sir, what is your preference?
Related
Tutorials:
A portable hill of
beans
A portable hill of
beans |
Reloading Applets
Reloading Applets |
Exceptions in
Java - JavaWorld - July
1998
Exceptions in
Java - JavaWorld - July
1998 |
How to attach a user interface to
a Jini service - JavaWorld October
1999
How to attach a user interface to
a Jini service - JavaWorld October
1999 |
Solve real problems with aglets, a type of
mobile agent - JavaWorld May 1997
Solve real problems with aglets, a type of
mobile agent - JavaWorld May 1997 |
Frameworks save the
day - JavaWorld September 2000
Frameworks save the
day - JavaWorld September 2000 |
Get smart with proxies and
RMI - JavaWorld
November 2000
Get smart with proxies and
RMI - JavaWorld
November 2000 |
Sun lets Jini
Starter Kit 1.1 out of the bottle - JavaWorld December
2000
Sun lets Jini
Starter Kit 1.1 out of the bottle - JavaWorld December
2000 |
Deliver
cellular messages with SMS - JavaWorld March 2001
Deliver
cellular messages with SMS - JavaWorld March 2001 |
Personalize your Website with skins - JavaWorld June
2001
Personalize your Website with skins - JavaWorld June
2001 |
Sir, what is your preference?
Sir, what is your preference? |
A recipe for cookie management
A recipe for cookie management |
Discover and publish Web services with JAXR
Discover and publish Web services with JAXR |
Effort on the
edge, Part 1
Effort on the
edge, Part 1 |
The first taste of Liberty
The first taste of Liberty |
Doclipse, a Javadoc tag plug-in for Eclipse
Doclipse
A JavaDoc Tag Plug-in for Eclipse |
Develop aspect-oriented Java applications with Eclipse and AJDT
AspectJ is an aspect-oriented extension of the Javaâ„¢ language that enables a modular implementation of crosscutting concerns. This crosscutting behavior, which can be static or dynamic, presents an extra challenge to tools that support AspectJ. The AJDT |
Getting Started With Composite Capabilities/Preference Profiles and JSR 188
This article presents Composite Capabilities/Preference Profiles for designing content once. JSR 188 allows users to access the same application or content from any device, and be confident that it will work on that device, and will accommodate their pref |
Adding slash "\" character before quote "'" in a query
Adding slash "\" character before quote "'" in a query
Adding slash " \ " character before quote " ' " in a query
During the inserting the records in the database if user enters the phrases like "What ' s your name?", database gives the error due |
Complete Webhosting Guide, Search Web hosts, Find Plans
Complete Webhosting Guide, Search Web hosts, Find Plans
The Complete Web Hosting Guide
RoseIndia.net is the complete beginner's guide to finding a web hosting company.
Introduction to Web Hosting
What is Web Hosting? Linux vs. Windows |
|
|
|