/* * Copyright 2003-2012 Yusuke Yamamoto * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package samurai.util; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JTextField; import java.awt.Component; import java.awt.Dimension; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; public final class Configuration implements Runnable { private Properties props; private String fileName; private String name; public Configuration(String name) { this.name = name; this.fileName = System.getProperty("user.home") + File.separator + "." + name + ".properties"; GUIResourceBundle resources = GUIResourceBundle.getInstance("default"); props = resources.getProperties(); try { FileInputStream fis = new FileInputStream(fileName); props.load(fis); fis.close(); } catch (IOException ioe) { // } Runtime.getRuntime().addShutdownHook(new Thread(this)); } public void run() { for (String key : watchRectangles.keySet()) { storeRectangle(key, watchRectangles.get(key)); } for (String key : watchLocations.keySet()) { storeLocation(key, watchLocations.get(key)); } try { this.save(); } catch (IOException ioe) { ioe.printStackTrace(); } } public int getInt(String key) { String theValue = props.getProperty(key); int returnValue; try { returnValue = Integer.parseInt(theValue); } catch (NumberFormatException nfe) { returnValue = -1; } return returnValue; } public void setInt(String key, int value) { props.setProperty(key, String.valueOf(value)); } public String getString(String key) { String theValue = props.getProperty(key); String returnValue; if (null == theValue) { returnValue = ""; } else { returnValue = theValue; } return returnValue; } public void setString(String key, String value) { props.setProperty(key, String.valueOf(value)); } public boolean getBoolean(String key) { String theValue = props.getProperty(key); boolean returnValue; if (null == theValue) { returnValue = false; } else { returnValue = theValue.equalsIgnoreCase("true"); } return returnValue; } public void setBoolean(String key, boolean value) { props.setProperty(key, String.valueOf(value)); } public Rectangle getRectangle(String key) { String theValue = props.getProperty(key); Rectangle returnValue; if (null == theValue) { returnValue = null; } else { String[] splitted = theValue.split(","); double x = Double.parseDouble(splitted[0]); double y = Double.parseDouble(splitted[1]); double width = Double.parseDouble(splitted[2]); double height = Double.parseDouble(splitted[3]); returnValue = new Rectangle((int) x, (int) y, (int) width, (int) height); } return returnValue; } public Point getLocation(String key) { String theValue = props.getProperty(key); Point returnValue; if (null == theValue) { returnValue = null; } else { String[] splitted = theValue.split(","); double x = Double.parseDouble(splitted[0]); double y = Double.parseDouble(splitted[1]); returnValue = new Point((int) x, (int) y); } return returnValue; } public void setLocation(String key, Point point) { props.setProperty(key, point.getX() + "," + point.getY()); } private void centerComponent(Component component) { Dimension frameSize = component.getSize(); Point frameLocation = component.getLocation(); if (10000 < frameLocation.getX() && 10000 < frameLocation.getY()) { //Center the window Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); if (frameSize.height > screenSize.height) { frameSize.height = screenSize.height; } if (frameSize.width > screenSize.width) { frameSize.width = screenSize.width; } component.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); } } public void setRectangle(String key, Rectangle value) { props.setProperty(key, value.getX() + "," + value.getY() + "," + value.getWidth() + "," + value.getHeight()); } private final Map<String, Component> watchRectangles = new HashMap<String, Component>(); public void applyRectangle(String key, Component component) { component.setBounds(getRectangle(key)); setRectangle(key, component.getBounds()); centerComponent(component); setRectangle(key, component.getBounds()); watchRectangles.put(key, component); } private final Map<String, Component> watchLocations = new HashMap<String, Component>(); public void applyLocation(String key, Component component) { component.setLocation(getLocation(key)); setLocation(key, component.getLocation()); centerComponent(component); setLocation(key, component.getLocation()); watchLocations.put(key, component); } public void storeRectangle(String key, Component component) { setRectangle(key, component.getBounds()); } public void storeLocation(String key, Component component) { setLocation(key, component.getLocation()); } public void save() throws IOException { System.out.println("Saving configuration.[" + this.fileName + "]"); props.store(new FileOutputStream(this.fileName), this.name); } public void apply(Object obj) { Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { String fieldName = field.getName(); if (fieldName.startsWith("config_")) { String property = fieldName.substring(7); Class type = field.getType(); try { if (type.equals(boolean.class)) { field.setBoolean(obj, getBoolean(property)); } else if (type.equals(int.class)) { field.setInt(obj, getInt(property)); } else if (type.equals(String.class)) { field.set(obj, getString(property)); } else if (type.equals(JCheckBox.class)) { ((JCheckBox) field.get(obj)).setSelected(getBoolean( property)); } else if (type.equals(JComboBox.class)) { JComboBox comboBox = (JComboBox) field.get(obj); comboBox.setSelectedItem(getString(property)); } else if (type.equals(JTextField.class)) { JTextField textField = (JTextField) field.get(obj); textField.setText(getString(property)); } } catch (IllegalAccessException iae) { throw new AssertionError(iae.getMessage()); } } } if (obj instanceof ConfigurationListener) { ((ConfigurationListener) obj).onConfigurationChanged(this); } } public void store(Object obj) { Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { String fieldName = field.getName(); if (fieldName.startsWith("config_")) { String property = fieldName.substring(7); Class type = field.getType(); try { if (type.equals(boolean.class)) { setBoolean(property, field.getBoolean(obj)); } else if (type.equals(int.class)) { setInt(property, field.getInt(obj)); } else if (type.equals(String.class)) { setString(property, (String) field.get(obj)); } else if (type.equals(JCheckBox.class)) { setBoolean(property, ((JCheckBox) field.get(obj)).isSelected()); } else if (type.equals(JComboBox.class)) { setString(property, (String) ((JComboBox) field.get(obj)).getSelectedItem()); } else if (type.equals(JTextField.class)) { setString(property, ((JTextField) field.get(obj)).getText()); } } catch (IllegalAccessException iae) { throw new AssertionError(iae.getMessage()); } } } } private List<Object> listenerList = new ArrayList<Object>(); public void addTarget(Object listener) { listenerList.add(listener); apply(listener); } public void notifyChange() { for (Object obj : listenerList) { apply(obj); if (obj instanceof ConfigurationListener) { ((ConfigurationListener) obj).onConfigurationChanged(this); } } } }