The JavaTM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Putting It All Together
Lesson: BINGO!

## Managing Program Settings in the Player

> The Player application provides a number of UI widgets that allow a user to change various settings such as the player's name, the number of cards to play, and whether to beep to announce each ball.

> [PENDING: put picture of player with callouts here]

> As you can see from the diagram, the settings for the Player application that the user can change are:

> - the player's name
> - the name of the machine on which the Game is running
> - the number of cards to play
> - whether the application should beep for each ball
> - the random number seed
> As an added convenience, the Player application remembers these settings between invocations so that each time the user invokes the Player application its UI can be initialized with the values used in the last game.

> One class is the central repository for all program settings in the Player: the `PlayerParameters` class. For each program setting, `PlayerParameters` declares one member variable to contain its current value, and two methods, one to set (or change) the value and one to get it. For example, here is the declaration for the member variable in `PlayerParameters` that stores the player's name, and the two methods that set and get it:

> >     . . .
> >     private String name = "";
> >     . . .
> >     void setName(String name) {
> >         this.name = name;
> >         saveParameters();
> >     }
> >     String getName() {
> >         return name;
> >     }

> Note that the `setName` method calls another method named `saveParameters` which saves the now changed properties to a file on the file system. All the settings but one, the random number seed, is remembered between invocations of the Player application.

> `PlayerParameters` manages the values of the settings for the program. The work of saving the settings to the Player's properties file and restoring them from the same file is done by its superclass `Parameters`.

> `Parameters` is an abstract class with three abstract methods that must be implemented by its subclasses. These three methods bridge setting values as maintained by the `PlayerParameters` class and their `String` representations saved to a file. `Parameters` uses the JDK's `Properties` class to store the `String` representation of each setting and save and restore them.

### How it Works

> When the Player first starts up, it loads the last-saved properties and uses them to initialize its UI. The Player and the Game use the JDK's `Properties` class to save and restore program settings, so they are stored as `String`s in as key/value pairs like this:

> >     player.shouldbeep=false
> >     server.name=taranis
> >     num.cards=3
> >     player.name=mary campione

> The method used to load the properties is implemented in `PlayerParameters`' superclass, `Parameters`, and looks like this:

> >     protected void getParameters() {
> >         Properties defaults = new Properties();
> >         FileInputStream in = null;

> >         setDefaults(defaults);

> >         properties = new Properties(defaults);

> >         try {
> >             String folder = System.getProperty("user.home");
> >             String filesep = System.getProperty("file.separator");
> >             in = new FileInputStream(folder
> >                 + filesep
> >                 + propertiesFilename);
> >             properties.load(in);

> >         } catch (java.io.FileNotFoundException e) {
> >             in = null;
> >             ErrorMessages.error("Can't find properties file. " +
> >                                 "Using defaults.");
> >         } catch (java.io.IOException e) {
> >             ErrorMessages.error("Can't read properties file. " +
> >                                 "Using defaults.");
> >         } finally {
> >             if (in != null) {
> >                 try { in.close(); } catch (java.io.IOException e) { }
> >                 in = null;
> >             }
> >         }

> >         updateSettingsFromProperties();

> >     }

> This method does three things:
> 1. calls `setDefaults` to set up default values which will be used if there are no properties saved or if there are any errors while reading them. (This method call is shown in bold)
> 2. loads the properties from the file. (This is the code in the big `try` statement.)
> 3. calls `updateSettingsFromProperties` to update the program settings from the properties just read. (This method call is also shown in bold.)
> Note that `setDefaults` and `updateSettingsFromProperties` are abstract methods in the `Parameters` class. These methods are implemented in its concrete subclasses such as `PlayerParameters`. This is appropriate because `Parameters` does the generic work of saving and restoring the properties and its two subclasses `PlayerParameters` and `GameParameters` manage the specific program settings for each program.

> Remember that the program settings are stored as human-readable text. `setDefaults` and `updateSettingsFromProperties` convert the values from `String`s to the appropriate type at this time.

> Whenever a program setting is modified and that change takes affect, the settings are saved to the file. For example, here's `PlayerParameters`'s `setHostname` method that changes the hostname.

> >     void setHostname(String hostname) {
> >         this.hostname = hostname;
> >         saveParameters();
> >     }

> This method calls `saveParameters` a method implemented by the parent class `Parameters`

> >     protected void saveParameters() {

> >         updatePropertiesFromSettings();

> >         if (DEBUG) {
> >             System.out.println("Just set properties: "
> >                                + propertiesDescription);
> >             System.out.println(toString());
> >         }

> >         FileOutputStream out = null;

> >         try {
> >             String folder = System.getProperty("user.home");
> >             String filesep = System.getProperty("file.separator");
> >             out = new FileOutputStream(folder
> >     			           + filesep
> >     			           + propertiesFilename);
> >             properties.save(out, propertiesDescription);
> >         } catch (java.io.IOException e) {
> >             ErrorMessages.error("Can't save properties. " +
> >     			    "Oh well, it's not a big deal.");
> >         } finally {
> >             if (out != null) {
> >     	    try { out.close(); } catch (java.io.IOException e) { }
> >     	    out = null;
> >             }
> >         }
> >     }

> This method converts the settings as stored in the program to `String`s by calling the `updatePropertiesFromSettings` method which is declared abstract in `Parameters` and implemented by `PlayerParameters`. Next the method saves the properties to a file.

> You should note the use of the JDK's `Properties` class to store the `String` representations of the program settings, and save and restore them to the file system.

### Managing the Game's Settings

> The Game application also provides a UI for modifying settings for the entire game (such as maximum number of players, maximum number of wolf cries and so on):

> [PENDING: put picture of game with callouts here]

> Like the Player application, the Game application uses one class, the `GameParameters` class, to manage its settings. `GameParameters` is also a subclass of `Parameters`. The code in this class is very similar to that in the Player and we leave it to you to figure out.

| Start of Tutorial > Start of Trail > Start of Lesson | Search