|
From: <ste...@us...> - 2010-07-17 20:27:29
|
Revision: 1344
http://rails.svn.sourceforge.net/rails/?rev=1344&view=rev
Author: stefanfrey
Date: 2010-07-17 20:27:23 +0000 (Sat, 17 Jul 2010)
Log Message:
-----------
Update configuration management
Modified Paths:
--------------
trunk/18xx/LocalisedText.properties
trunk/18xx/data/Properties.xml
trunk/18xx/rails/ui/swing/ConfigWindow.java
trunk/18xx/rails/util/Config.java
trunk/18xx/rails/util/ConfigItem.java
Modified: trunk/18xx/LocalisedText.properties
===================================================================
--- trunk/18xx/LocalisedText.properties 2010-07-17 15:06:13 UTC (rev 1343)
+++ trunk/18xx/LocalisedText.properties 2010-07-17 20:27:23 UTC (rev 1344)
@@ -64,6 +64,7 @@
CLOSE_WINDOW=Do you really want to exit the game?
COMPANY=Company
COMPANY_DETAILS=Company details
+CONFIG_CURRENT_PROFILE=Active profile = {0} (based on = {1})
CORRECT_CASH=Cash Correction
CORRECT_MAP=Map Correction
CURRENT=Current
Modified: trunk/18xx/data/Properties.xml
===================================================================
--- trunk/18xx/data/Properties.xml 2010-07-17 15:06:13 UTC (rev 1343)
+++ trunk/18xx/data/Properties.xml 2010-07-17 20:27:23 UTC (rev 1344)
@@ -4,7 +4,7 @@
-->
<Properties>
<Panel name="General">
- <Property name="locale" type="STRING"/>
+ <Property name="locale" type="LIST" values="en_US,de" />
</Panel>
<Panel name="Colors">
<Property name="route.colour.1" type="COLOR"/>
Modified: trunk/18xx/rails/ui/swing/ConfigWindow.java
===================================================================
--- trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-17 15:06:13 UTC (rev 1343)
+++ trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-17 20:27:23 UTC (rev 1344)
@@ -2,29 +2,49 @@
import java.awt.Color;
import java.awt.Component;
+import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.io.File;
import java.util.Map;
import java.util.List;
+import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
+import javax.swing.JComboBox;
import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.filechooser.FileFilter;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
+import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
+import javax.swing.SpinnerListModel;
+import javax.swing.SwingConstants;
+import javax.swing.border.Border;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import rails.game.ConfigurationException;
import rails.util.Config;
import rails.util.ConfigItem;
import rails.util.LocalText;
+import rails.util.Util;
class ConfigWindow extends JFrame {
private static final long serialVersionUID = 1L;
- private JTabbedPane pane;
+ private JPanel profilePanel;
+ private JTabbedPane configPane;
+ private JPanel buttonPanel;
ConfigWindow() {
// JFrame properties
@@ -32,55 +52,66 @@
// setSize(400,300);
// add profile panel
- add(setupProfilePanel(), "North");
+ profilePanel = new JPanel();
+ add(profilePanel, "North");
// configSetup pane
- setupConfigPane();
- add(pane, "Center");
+ configPane = new JTabbedPane();
+ add(configPane, "Center");
// buttons
- JPanel buttonPanel = new JPanel();
-
- JButton saveButton = new JButton(LocalText.getText("Save"));
- saveButton.addActionListener(
- new ActionListener() {
- public void actionPerformed(ActionEvent arg0) {
- ConfigWindow.this.saveConfig();
- }
- }
- );
- buttonPanel.add(saveButton);
+ buttonPanel = new JPanel();
+ add(buttonPanel, "South");
- JButton cancelButton = new JButton(LocalText.getText("Cancel"));
- cancelButton.addActionListener(
- new ActionListener() {
- public void actionPerformed(ActionEvent arg0) {
- ConfigWindow.this.cancelConfig();
- }
- }
- );
- buttonPanel.add(cancelButton);
-
- add(buttonPanel, "South");
-
+ init();
+ }
+
+ private void init() {
+ setupProfilePanel();
+ setupConfigPane();
+ setupButtonPanel();
this.pack();
}
-
- private JComponent setupProfilePanel() {
- JComponent panel = new JPanel();
- panel.setLayout(new GridLayout(0,4));
+ private void setupProfilePanel() {
+ profilePanel.removeAll();
- // default profile
+ profilePanel.setLayout(new GridLayout(0,4));
+ String activeProfile = Config.getActiveProfileName();
+ String defaultProfile = Config.getDefaultProfileName();
+ Border etched = BorderFactory.createEtchedBorder();
+ Border titled = BorderFactory.createTitledBorder(etched, LocalText.getText("CONFIG_CURRENT_PROFILE", activeProfile, defaultProfile));
+ profilePanel.setBorder(titled);
- return panel;
+ JLabel userLabel = new JLabel(LocalText.getText("CONFIG_SELECT_USER"));
+ profilePanel.add(userLabel);
+ final JComboBox comboBoxUser = new JComboBox(Config.getUserProfiles().toArray());
+ comboBoxUser.setSelectedItem(Config.getActiveProfileName());
+ comboBoxUser.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent arg0) {
+ Config.changeActiveProfile((String)comboBoxUser.getSelectedItem());
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ init();
+ ConfigWindow.this.repaint();
+ }
+ }
+ );
+ }
+ }
+ );
+ profilePanel.add(comboBoxUser);
+
}
private void setupConfigPane() {
- // create pane
- pane = new JTabbedPane();
+ configPane.removeAll();
+ Border etched = BorderFactory.createEtchedBorder();
+ Border titled = BorderFactory.createTitledBorder(etched, LocalText.getText("CONFIG_SETTINGS"));
+ configPane.setBorder(titled);
+
Map<String, List<ConfigItem>> configPanels = Config.getConfigPanels();
for (String panelName:configPanels.keySet()) {
@@ -89,54 +120,153 @@
for (ConfigItem item:configPanels.get(panelName)) {
defineElement(newPanel, item);
}
- pane.addTab(panelName, newPanel);
+ configPane.addTab(panelName, newPanel);
}
}
- private void defineElement(JPanel panel, ConfigItem item) {
-
+ private void defineElement(JPanel panel, final ConfigItem item) {
+ // item label
panel.add(new JLabel(LocalText.getText("Config." + item.name)));
- final String configValue = Config.get(item.name);
+ // standard components
+ final String configValue = item.getCurrentValue();
+
+
switch (item.type) {
- case COLOR: {
+ case COLOR:
final JLabel label = new JLabel(configValue);
Color selectedColor;
try {
- selectedColor = Color.decode(configValue);
- } catch (NumberFormatException e) {
+ selectedColor = Util.parseColour(configValue);
+ } catch (ConfigurationException e) {
selectedColor = Color.WHITE;
}
label.setOpaque(true);
+ label.setHorizontalAlignment(SwingConstants.CENTER);
label.setBackground(selectedColor);
+ if (Util.isDark(selectedColor)) {
+ label.setForeground(Color.WHITE);
+ } else {
+ label.setForeground(Color.BLACK);
+ }
panel.add(label);
- JButton button = new JButton("Color");
+ JButton button = new JButton("Choose...");
final Color oldColor = selectedColor;
button.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
Color selectedColor=JColorChooser.showDialog(ConfigWindow.this, "", oldColor);
- label.setText(Integer.toHexString(selectedColor.getRGB()).substring(2));
+ if (selectedColor == null) return;
+ String newValue = Integer.toHexString(selectedColor.getRGB()).substring(3);
+ label.setText(newValue);
+ item.setNewValue(newValue);
label.setBackground(selectedColor);
+ if (Util.isDark(selectedColor)) {
+ label.setForeground(Color.WHITE);
+ } else {
+ label.setForeground(Color.BLACK);
+ }
}
}
);
panel.add(button);
break;
- }
+ case LIST:
+ final JComboBox comboBox = new JComboBox(item.allowedValues.toArray());
+ comboBox.setSelectedItem(configValue);
+ comboBox.addFocusListener(new FocusListener() {
+ public void focusGained(FocusEvent arg0) {
+ // do nothing
+ }
+ public void focusLost(FocusEvent arg0) {
+ item.setNewValue((String)comboBox.getSelectedItem());
+ }
+ }
+ );
+ panel.add(comboBox);
+ break;
case STRING:
- default: {
- JFormattedTextField textField = new JFormattedTextField();
+ default: // default like String
+ final JFormattedTextField textField = new JFormattedTextField();
textField.setValue(configValue);
+ textField.addFocusListener(new FocusListener() {
+ public void focusGained(FocusEvent arg0) {
+ // do nothing
+ }
+ public void focusLost(FocusEvent arg0) {
+ item.setNewValue(textField.getText());
+ }
+ }
+ );
panel.add(textField);
+ break;
}
+ }
+
+ private void setupButtonPanel() {
+ buttonPanel.removeAll();
+
+ // save button
+ if (Config.isFilePathDefined()) {
+ JButton saveButton = new JButton(LocalText.getText("SAVE"));
+ saveButton.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ ConfigWindow.this.saveConfig();
+ }
+ }
+ );
+ buttonPanel.add(saveButton);
}
+
+ JButton saveAsButton = new JButton(LocalText.getText("SAVEAS"));
+ saveAsButton.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ ConfigWindow.this.saveAsConfig();
+ }
+ }
+ );
+ buttonPanel.add(saveAsButton);
+
+ JButton cancelButton = new JButton(LocalText.getText("CANCEL"));
+ cancelButton.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ ConfigWindow.this.cancelConfig();
+ }
+ }
+ );
+ buttonPanel.add(cancelButton);
+
}
private void saveConfig() {
this.dispose();
}
+ private void saveAsConfig() {
+ JFileChooser fc = new JFileChooser();
+ fc.setFileFilter(
+ new FileFilter() {
+ public boolean accept( File f ){
+ return f.isDirectory() ||
+ f.getName().toLowerCase().endsWith( ".rails_config" );
+ }
+ public String getDescription() {
+ return "Rails Config";
+ }
+ }
+ );
+
+ int state = fc.showOpenDialog( null );
+ if ( state == JFileChooser.APPROVE_OPTION )
+ {
+ File file = fc.getSelectedFile();
+ Config.setActiveFilepath(file.getPath());
+ }
+ }
+
private void cancelConfig() {
this.dispose();
}
Modified: trunk/18xx/rails/util/Config.java
===================================================================
--- trunk/18xx/rails/util/Config.java 2010-07-17 15:06:13 UTC (rev 1343)
+++ trunk/18xx/rails/util/Config.java 2010-07-17 20:27:23 UTC (rev 1344)
@@ -8,10 +8,13 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
import org.apache.log4j.Logger;
@@ -31,13 +34,6 @@
protected static Logger log =
Logger.getLogger(Config.class.getPackage().getName());
-
- /**
- * Defines possible types (Java classes used as types in ConfigItem below
- */
- public static enum ConfigType {
- INTEGER, FLOAT, STRING, BOOLEAN, DIRECTORY, COLOR;
- }
/** XML setup */
private static final String CONFIG_XML_DIR = "data";
@@ -59,12 +55,11 @@
private static final String TEST_PROFILE_SELECTION = "test";
private static final String DEFAULT_PROFILE_SELECTION = "default";
private static final String DEFAULT_PROFILE_PROPERTY = "default.profile";
- private static final String STANDARD_PROFILE_PROPERTY = "standard.profile";
+ private static final String STANDARD_PROFILE_SELECTION = "user";
/** selected profile */
private static String selectedProfile;
private static boolean legacyConfigFile;
- private static boolean standardProfile;
/** properties storage. */
private static Properties defaultProperties = new Properties();
@@ -157,20 +152,13 @@
}
-// /**
-// * store user config file
-// */
-// public static boolean saveUserConfig() {
-// }
-//
-// /**
-// * @return if user location is defined
-// */
-// public static boolean hasUserLocation() {
-// return userConfigFile != null;
-// }
+ /**
+ * @return if user location is defined
+ */
+ public static boolean isFilePathDefined() {
+ return Util.hasValue(userProfiles.getProperty(selectedProfile));
+ }
-
private static boolean storePropertyFile(Properties properties, String filepath) {
File outFile = new File(filepath);
boolean result = true;
@@ -192,24 +180,46 @@
/**
* change active Profile
*/
- public static boolean setActiveProfile(String profileName) {
- boolean result = loadPropertyProfile(profileName);
- if (result) selectedProfile = profileName;
- return result;
+ public static boolean changeActiveProfile(String profileName) {
+ readConfigSetupXML();
+ loadPropertyProfile(profileName);
+ selectedProfile = profileName;
+ return true;
}
+ private static Map<String, String> convertProperties(Properties properties) {
+ Map<String, String> converted = new HashMap<String, String>();
+ for (Object key:properties.keySet()) {
+ converted.put((String) key, (String) properties.get(key));
+ }
+ return converted;
+ }
+
+
+ /**
+ * get all default profiles
+ */
+ public static List<String> getDefaultProfiles() {
+ List<String> profiles = new ArrayList<String>(convertProperties(defaultProfiles).keySet());
+ profiles.remove(DEFAULT_PROFILE_PROPERTY);
+ Collections.sort(profiles);
+ return profiles;
+ }
+
+ /**
+ * get all user profiles
+ */
+ public static List<String> getUserProfiles() {
+ List<String> profiles = new ArrayList<String>(convertProperties(userProfiles).keySet());
+ Collections.sort(profiles);
+ return profiles;
+ }
+
/**
* returns name of (active) default profile
*/
public static String getDefaultProfileName() {
- String defaultProfileName = null;
- if (isUserProfileActive()) {
- defaultProfileName = userProfiles.getProperty(DEFAULT_PROFILE_PROPERTY);
- if (defaultProfileName == null) {
-// return
- }
- }
- return defaultProfileName;
+ return userProperties.getProperty(DEFAULT_PROFILE_PROPERTY);
}
/**
@@ -235,13 +245,6 @@
}
/**
- * returns true if active profile is a user profile
- */
- public static boolean isUserProfileActive() {
- return userProfiles.getProperty(selectedProfile) != null;
- }
-
- /**
* activates settings used for testing
*/
public static void setConfigTest() {
@@ -290,9 +293,8 @@
}
/* if nothing has selected so far, choose standardProfile */
- standardProfile = false;
if (!Util.hasValue(configSelection)) {
- standardProfile = true;
+ configSelection = STANDARD_PROFILE_SELECTION;
}
selectedProfile = configSelection;
@@ -303,7 +305,7 @@
private static void initialLoad() {
if (legacyConfigFile) {
if (!propertiesLoaded) {
- loadPropertyFile(defaultProperties, selectedProfile, true, false);
+ loadPropertyFile(defaultProperties, selectedProfile, false);
propertiesLoaded = true;
setSaveDirDefaults();
}
@@ -311,45 +313,47 @@
}
if (!profilesLoaded) {
- loadPropertyFile(defaultProfiles, defaultProfilesFile, true, false);
- loadPropertyFile(userProfiles, userProfilesFile, false, false);
+ loadPropertyFile(defaultProfiles, defaultProfilesFile, true);
+ loadPropertyFile(userProfiles, userProfilesFile, false);
profilesLoaded = true;
}
- if (standardProfile) {
- selectedProfile = userProfiles.getProperty(STANDARD_PROFILE_PROPERTY);
- if (selectedProfile == null) {
- selectedProfile = defaultProfiles.getProperty(STANDARD_PROFILE_PROPERTY);
- }
- if (selectedProfile == null) {
- selectedProfile = DEFAULT_PROFILE_SELECTION;
- }
- }
-
/* Tell the properties loader to read this file. */
log.info("Selected profile = " + selectedProfile);
if (!propertiesLoaded) {
- propertiesLoaded = loadPropertyProfile(selectedProfile);
+ loadPropertyProfile(selectedProfile);
+ propertiesLoaded = true;
}
}
- private static boolean loadPropertyProfile(String profileName) {
+ /**
+ * loads a user profile and the according default profile
+ * if not defined or loadable, creates a default user profile
+ */
+ private static void loadPropertyProfile(String userProfile) {
+ // reset properties
+ userProperties = new Properties();
+ defaultProperties = new Properties();
- /* first check if it is a default profile */
- String defaultConfigFile = defaultProfiles.getProperty(profileName);
+ // check if the profile is already defined under userProfiles
+ String userConfigFile = userProfiles.getProperty(userProfile);
+ String defaultConfigFile = null;
+ if (Util.hasValue(userConfigFile) && // load user profile
+ loadPropertyFile(userProperties, userConfigFile, false)) {
+ String defaultConfig = userProperties.getProperty(DEFAULT_PROFILE_PROPERTY);
+ if (defaultConfig != null) {
+ defaultConfigFile = defaultProfiles.getProperty(defaultConfig);
+ }
+ } else {
+ userProfiles.setProperty(userProfile, "");
+ }
if (defaultConfigFile == null) {
- String userConfigFile = userProfiles.getProperty(profileName);
- if (userConfigFile == null) return false;
- loadPropertyFile(userProperties, userConfigFile, false, false);
- defaultConfigFile = userProperties.getProperty(DEFAULT_PROFILE_PROPERTY);
- if (defaultConfigFile == null) {
- defaultConfigFile = defaultProfiles.getProperty(DEFAULT_PROFILE_SELECTION);
- }
+ defaultConfigFile = defaultProfiles.getProperty(DEFAULT_PROFILE_SELECTION);
+ userProperties.setProperty(DEFAULT_PROFILE_PROPERTY, DEFAULT_PROFILE_SELECTION);
}
- loadPropertyFile(defaultProperties, defaultConfigFile, true, false);
+ loadPropertyFile(defaultProperties, defaultConfigFile, true);
setSaveDirDefaults();
- return true;
}
/**
@@ -357,11 +361,11 @@
*
* @param filename - file key name as a String.
* @param resource - if TRUE, loaded from jar (via classloader), otherwise from filesystem
- * @param required - if TRUE, an exception will be logged if the file does
- * not exist.
+ * @return TRUE if load was successful
*/
- private static void loadPropertyFile(Properties properties, String filename, boolean resource, boolean required) {
+ private static boolean loadPropertyFile(Properties properties, String filename, boolean resource) {
+ boolean result = true;
try {
log.info("Loading properties from file " + filename);
InputStream inFile;
@@ -371,15 +375,13 @@
inFile = new FileInputStream(filename);
}
properties.load(inFile);
- } catch (FileNotFoundException FNFE) {
- if (required) {
- System.err.println("File not found: " + filename);
- }
} catch (Exception e) {
System.err.println(e + " whilst loading properties file "
+ filename);
e.printStackTrace(System.err);
+ result = false;
}
+ return result;
}
private static void setSaveDirDefaults() {
Modified: trunk/18xx/rails/util/ConfigItem.java
===================================================================
--- trunk/18xx/rails/util/ConfigItem.java 2010-07-17 15:06:13 UTC (rev 1343)
+++ trunk/18xx/rails/util/ConfigItem.java 2010-07-17 20:27:23 UTC (rev 1344)
@@ -2,21 +2,38 @@
import java.util.Arrays;
import java.util.List;
+
+import org.apache.log4j.Logger;
+
import rails.game.ConfigurationException;
-import rails.util.Config.ConfigType;
/**
* Defines an item used for the configuration of rails
* T represents the value type
*/
-public class ConfigItem {
+public final class ConfigItem {
+
+ protected static Logger log =
+ Logger.getLogger(ConfigItem.class.getPackage().getName());
+
+ /**
+ * Defines possible types (Java classes used as types in ConfigItem below
+ */
+ public static enum ConfigType {
+ INTEGER, FLOAT, STRING, BOOLEAN, LIST, DIRECTORY, COLOR;
+ }
+
+ // static attributes
public final String name;
public final ConfigType type;
public final List<String> allowedValues;
public final String formatMask;
public final String helpText;
+ // dynamic attributes
+ private String newValue;
+
ConfigItem(Tag tag) throws ConfigurationException {
// check name and type (required)
String name = tag.getAttributeAsString("name");
@@ -25,29 +42,68 @@
} else {
throw new ConfigurationException("Missing name for configuration item");
}
- String type = tag.getAttributeAsString("type");
- if (Util.hasValue(type)) {
- this.type = ConfigType.valueOf(type);
- } else {
- throw new ConfigurationException("Missing or invalid type for configuration item");
- }
// optional: list of allowed values
String valueString = tag.getAttributeAsString("values");
if (Util.hasValue(valueString)) {
allowedValues = Arrays.asList(valueString.split(","));
+ this.type = ConfigType.LIST;
} else {
allowedValues = null;
+ String type = tag.getAttributeAsString("type");
+ if (Util.hasValue(type)) {
+ try {
+ this.type = ConfigType.valueOf(type.toUpperCase());
+ } catch (Exception e) {
+ throw new ConfigurationException("Missing or invalid type for configuration item");
+ }
+ } else {
+ throw new ConfigurationException("Missing or invalid type for configuration item");
+ }
+ if (this.type == ConfigType.LIST) {
+ throw new ConfigurationException("No values defined for LIST config item");
+ }
}
+
// optional: formatMask
formatMask = tag.getAttributeAsString("formatMask");
// optional: helpText
helpText = tag.getAttributeAsString("formatMask");
+
+ newValue = null;
}
+ public boolean hasNewValue() {
+ return (newValue != null);
+ }
+
+ public String getNewValue() {
+ return newValue;
+ }
+
+ public void setNewValue(String newValue) {
+ if (newValue.equals(getConfigValue())) {
+ this.newValue = null;
+ } else {
+ this.newValue = newValue;
+ }
+ log.debug("ConfigItem " + name + " set to new value " + this.newValue);
+ }
+
+ public String getCurrentValue() {
+ if (newValue != null) return newValue;
+ return getConfigValue();
+ }
+
+ public String getConfigValue() {
+ return Config.get(this.name);
+ }
+
public String toString() {
StringBuffer s = new StringBuffer();
s.append("Configuration Item: name = " + name + ", type = " + type);
+ s.append(", config value = " + getConfigValue());
+ s.append(", current value = " + getCurrentValue());
if (allowedValues != null) {
s.append(", allowedValues = " + allowedValues);
}
@@ -57,6 +113,7 @@
if (helpText != null) {
s.append(", helpText = " + helpText);
}
+
return s.toString();
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|