package net.sf.openrocket.rocketcomponent; import java.util.EventObject; import java.util.HashMap; import java.util.Iterator; import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.Utils; /** * An implementation of FlightConfiguration that fires off events * to the rocket components when the parameter value is changed. * * @param <E> the parameter type */ class FlightConfigurationImpl<E extends FlightConfigurableParameter<E>> implements FlightConfiguration<E> { private final HashMap<String, E> map = new HashMap<String, E>(); private E defaultValue = null; private final RocketComponent component; private final int eventType; private final Listener listener = new Listener(); /** * Construct a FlightConfiguration that has no overrides. * * @param component the rocket component on which events are fired when the parameter values are changed * @param eventType the event type that will be fired on changes * @param defaultValue the default value (null not allowed) */ public FlightConfigurationImpl(RocketComponent component, int eventType, E defaultValue) { this.component = component; this.eventType = eventType; this.defaultValue = defaultValue; if (defaultValue == null) { throw new NullPointerException("defaultValue is null"); } add(defaultValue); } /** * Construct a copy of an existing FlightConfigurationImpl. * * @param component the rocket component on which events are fired when the parameter values are changed * @param eventType the event type that will be fired on changes */ public FlightConfigurationImpl(FlightConfigurationImpl<E> flightConfiguration, RocketComponent component, int eventType) { this.component = component; this.eventType = eventType; this.defaultValue = flightConfiguration.defaultValue.clone(); for (String key : flightConfiguration.map.keySet()) { this.map.put(key, flightConfiguration.map.get(key).clone()); } } @Override public E getDefault() { return defaultValue; } @Override public void setDefault(E value) { if (value == null) { throw new NullPointerException("value is null"); } if (Utils.equals(this.defaultValue, value)) { return; } remove(this.defaultValue); this.defaultValue = value; add(value); fireEvent(); } @Override public Iterator<E> iterator() { return map.values().iterator(); } @Override public int size() { return map.size(); } @Override public E get(String id) { if (map.containsKey(id)) { return map.get(id); } else { return defaultValue; } } @Override public void set(String id, E value) { if (value == null) { throw new NullPointerException("value is null"); } E previous = map.put(id, value); remove(previous); add(value); fireEvent(); } @Override public boolean isDefault(String id) { return !map.containsKey(id); } @Override public void resetDefault(String id) { E previous = map.remove(id); remove(previous); fireEvent(); } private void fireEvent() { component.fireComponentChangeEvent(eventType); } @Override public void cloneFlightConfiguration(String oldConfigId, String newConfigId) { if (isDefault(oldConfigId)) { this.resetDefault(newConfigId); } else { E original = this.get(oldConfigId); this.set(newConfigId, original.clone()); } } private void add(E value) { if (value != null) { value.addChangeListener(listener); } } private void remove(E value) { if (value != null) { value.removeChangeListener(listener); } } private class Listener implements StateChangeListener { @Override public void stateChanged(EventObject e) { fireEvent(); } } }