From 5cc403368ec76f2c139b6ebb8c407ff71692ee04 Mon Sep 17 00:00:00 2001 From: Craig Earls Date: Wed, 24 Dec 2014 15:43:12 -0800 Subject: [PATCH] Split all panels, implement new launch preferences panel. --- core/resources/l10n/messages.properties | 8 +- .../DefaultSimulationOptionFactory.java | 6 +- .../simulation/SimulationOptions.java | 37 +- .../sf/openrocket/startup/Preferences.java | 355 ++++++- .../preferences/DesignPreferencesPanel.java | 80 ++ ...anel.java => DisplayPreferencesPanel.java} | 4 +- .../preferences/GeneralPreferencesPanel.java | 293 ++++++ .../preferences/GraphicsPreferencesPanel.java | 186 ++++ .../preferences/LaunchPreferencesPanel.java | 448 +++++++++ .../preferences/PreferencesDialog.java | 948 +----------------- .../dialogs/preferences/PreferencesPanel.java | 193 ++++ .../SimulationPreferencesPanel.java | 85 ++ .../preferences/UnitsPreferencesPanel.java | 174 ++++ 13 files changed, 1847 insertions(+), 970 deletions(-) create mode 100644 swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java rename swing/src/net/sf/openrocket/gui/dialogs/preferences/{ColorDefaultsPanel.java => DisplayPreferencesPanel.java} (66%) create mode 100644 swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java create mode 100644 swing/src/net/sf/openrocket/gui/dialogs/preferences/GraphicsPreferencesPanel.java create mode 100644 swing/src/net/sf/openrocket/gui/dialogs/preferences/LaunchPreferencesPanel.java create mode 100644 swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesPanel.java create mode 100644 swing/src/net/sf/openrocket/gui/dialogs/preferences/SimulationPreferencesPanel.java create mode 100644 swing/src/net/sf/openrocket/gui/dialogs/preferences/UnitsPreferencesPanel.java diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 5ebd0c9cd..5afdc0607 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -256,6 +256,7 @@ pref.dlg.tab.Custommaterials = Custom materials pref.dlg.tab.Options = General pref.dlg.tab.Design = Design pref.dlg.tab.Simulation = Simulation +pref.dlg.tab.Launch = Launch pref.dlg.tab.Miscellaneousoptions = Miscellaneous options pref.dlg.tab.Graphics = Graphics @@ -270,7 +271,7 @@ pref.dlg.ttip.DefaultMach1 = This setting will take effect the next tim pref.dlg.ttip.DefaultMach2 = To change the CP Mach number during this session use Tools->Component Analysis. pref.dlg.lbl.Positiontoinsert = Position to insert new body components: -pref.dlg.lbl.Confirmdeletion = Confirm deletion of simulations: +pref.dlg.lbl.Confirmdeletion = Confirm deletion of simulations. pref.dlg.checkbox.Runsimulations = Run out-dated simulations when you open the simulation tab. pref.dlg.checkbox.Updateestimates = Update estimated flight parameters in design window pref.dlg.lbl.User-definedthrust = User-defined thrust curves: @@ -324,6 +325,11 @@ PreferencesDialog.lbl.language = Interface language: PreferencesDialog.languages.default = System default PreferencesDialog.lbl.languageEffect = The language will change the next time you start OpenRocket. +generalprefs.lbl.language = Interface language +generalprefs.languages.default = System default +generalprefs.lbl.languageEffect = The language will change the next time you start OpenRocket. + + ! Simulation edit dialog simedtdlg.but.runsimulation = Run simulation simedtdlg.but.resettodefault = Reset to default diff --git a/core/src/net/sf/openrocket/simulation/DefaultSimulationOptionFactory.java b/core/src/net/sf/openrocket/simulation/DefaultSimulationOptionFactory.java index a60956f36..785598c59 100644 --- a/core/src/net/sf/openrocket/simulation/DefaultSimulationOptionFactory.java +++ b/core/src/net/sf/openrocket/simulation/DefaultSimulationOptionFactory.java @@ -19,6 +19,7 @@ public class DefaultSimulationOptionFactory { public static final String SIMCONDITION_ATMOS_STD = "SimConditionsAtmosStd"; public static final String SIMCONDITION_ATMOS_TEMP = "SimConditionsAtmosTemp"; public static final String SIMCONDITION_ATMOS_PRESSURE = "SimConditionsAtmosPres"; + public static final String SIMCONDITION_ROD_INTO_WIND = "SimConditionsRodIntoWind"; public static final String SIMCONDITION_ROD_LENGTH = "SimConditionsRodLength"; public static final String SIMCONDITION_ROD_ANGLE = "SimConditionsRodAngle"; public static final String SIMCONDITION_ROD_DIRECTION = "SimConditionsRodDirection"; @@ -45,7 +46,9 @@ public class DefaultSimulationOptionFactory { defaults.setISAAtmosphere(prefs.getBoolean(SIMCONDITION_ATMOS_STD, defaults.isISAAtmosphere())); defaults.setLaunchTemperature(prefs.getDouble(SIMCONDITION_ATMOS_TEMP, defaults.getLaunchTemperature())); + defaults.setLaunchPressure(prefs.getDouble(SIMCONDITION_ATMOS_PRESSURE, defaults.getLaunchTemperature())); + defaults.setLaunchIntoWind(prefs.getBoolean(SIMCONDITION_ROD_INTO_WIND, defaults.getLaunchIntoWind())); defaults.setLaunchRodLength(prefs.getDouble(SIMCONDITION_ROD_LENGTH, defaults.getLaunchRodLength())); defaults.setLaunchRodAngle(prefs.getDouble(SIMCONDITION_ROD_ANGLE, defaults.getLaunchRodAngle())); defaults.setLaunchRodDirection(prefs.getDouble(SIMCONDITION_ROD_DIRECTION, defaults.getLaunchRodDirection())); @@ -62,10 +65,11 @@ public class DefaultSimulationOptionFactory { prefs.putDouble(SIMCONDITION_SITE_LAT, newDefaults.getLaunchLatitude()); prefs.putDouble(SIMCONDITION_SITE_LON, newDefaults.getLaunchLongitude()); prefs.putDouble(SIMCONDITION_SITE_ALT, newDefaults.getLaunchAltitude()); - prefs.putBoolean(SIMCONDITION_ATMOS_STD, newDefaults.isISAAtmosphere()); prefs.putDouble(SIMCONDITION_ATMOS_TEMP, newDefaults.getLaunchTemperature()); + prefs.putDouble(SIMCONDITION_ATMOS_PRESSURE, newDefaults.getLaunchPressure()); + prefs.putBoolean(SIMCONDITION_ROD_INTO_WIND, newDefaults.getLaunchIntoWind()); prefs.putDouble(SIMCONDITION_ROD_LENGTH, newDefaults.getLaunchRodLength()); prefs.putDouble(SIMCONDITION_ROD_ANGLE, newDefaults.getLaunchRodAngle()); prefs.putDouble(SIMCONDITION_ROD_DIRECTION, newDefaults.getLaunchRodDirection()); diff --git a/core/src/net/sf/openrocket/simulation/SimulationOptions.java b/core/src/net/sf/openrocket/simulation/SimulationOptions.java index b1a16c18a..0769a0b5e 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationOptions.java +++ b/core/src/net/sf/openrocket/simulation/SimulationOptions.java @@ -16,6 +16,7 @@ import net.sf.openrocket.models.gravity.WGSGravityModel; import net.sf.openrocket.models.wind.PinkNoiseWindModel; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.startup.Preferences; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.GeodeticComputationStrategy; @@ -45,6 +46,7 @@ public class SimulationOptions implements ChangeSource, Cloneable { */ private static final AtmosphericModel ISA_ATMOSPHERIC_MODEL = new ExtendedISAModel(); + protected final Preferences preferences = Application.getPreferences(); private final Rocket rocket; private String motorID = null; @@ -55,36 +57,29 @@ public class SimulationOptions implements ChangeSource, Cloneable { * equals and copyFrom methods!! */ - // TODO: HIGH: Fetch default values from Prefs! - - private double launchRodLength = 1; - - /** Keep launch rod parallel to wind*/ - private boolean launchIntoWind = true; - /** Launch rod angle, |radians|<90 from vertical, positive is upwind, negative is downwind */ - private double launchRodAngle = 0; - - /** Launch rod direction, 0 = north. */ - private double windDirection = Math.PI / 2; - private double launchRodDirection = 0; + private double launchRodLength = preferences.getDouble(Preferences.LAUNCH_ROD_LENGTH, 1); + private boolean launchIntoWind = preferences.getBoolean(Preferences.LAUNCH_INTO_WIND, true); + private double launchRodAngle = preferences.getDouble(Preferences.LAUNCH_ROD_ANGLE, 0); + private double windDirection = preferences.getDouble(Preferences.WIND_DIRECTION, Math.PI / 2); + private double launchRodDirection = preferences.getDouble(Preferences.LAUNCH_ROD_DIRECTION, Math.PI / 2); - private double windAverage = 2.0; - private double windTurbulence = 0.1; + private double windAverage = preferences.getDouble(Preferences.WIND_AVERAGE, 2.0); + private double windTurbulence = preferences.getDouble(Preferences.WIND_TURBULANCE, 0.1); /* * SimulationOptions maintains the launch site parameters as separate double values, * and converts them into a WorldCoordinate when converting to SimulationConditions. */ - private double launchAltitude = 0; - private double launchLatitude = 45; - private double launchLongitude = 0; + + private double launchAltitude = preferences.getDouble(Preferences.LAUNCH_ALTITUDE, 0); + private double launchLatitude = preferences.getDouble(Preferences.LAUNCH_LATITUDE, 28.61); + private double launchLongitude = preferences.getDouble(Preferences.LAUNCH_LONGITUDE, -80.60); private GeodeticComputationStrategy geodeticComputation = GeodeticComputationStrategy.SPHERICAL; - private boolean useISA = true; - private double launchTemperature = ExtendedISAModel.STANDARD_TEMPERATURE; - private double launchPressure = ExtendedISAModel.STANDARD_PRESSURE; - + private boolean useISA = preferences.getBoolean(Preferences.LAUNCH_USE_ISA, true); + private double launchTemperature = preferences.getDouble(Preferences.LAUNCH_TEMPERATURE, ExtendedISAModel.STANDARD_TEMPERATURE); + private double launchPressure = preferences.getDouble(Preferences.LAUNCH_PRESSURE, ExtendedISAModel.STANDARD_PRESSURE); private double timeStep = RK4SimulationStepper.RECOMMENDED_TIME_STEP; private double maximumAngle = RK4SimulationStepper.RECOMMENDED_ANGLE_STEP; diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java index 1044f9368..6b6ce216c 100644 --- a/core/src/net/sf/openrocket/startup/Preferences.java +++ b/core/src/net/sf/openrocket/startup/Preferences.java @@ -10,6 +10,8 @@ import java.util.Set; import net.sf.openrocket.database.Databases; import net.sf.openrocket.material.Material; +import net.sf.openrocket.models.atmosphere.AtmosphericModel; +import net.sf.openrocket.models.atmosphere.ExtendedISAModel; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.rocketcomponent.BodyComponent; import net.sf.openrocket.rocketcomponent.FinSet; @@ -28,16 +30,14 @@ import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.UniqueID; public abstract class Preferences implements ChangeSource { - + /* * Well known string keys to preferences. * There are other strings out there in the source as well. */ public static final String BODY_COMPONENT_INSERT_POSITION_KEY = "BodyComponentInsertPosition"; public static final String USER_THRUST_CURVES_KEY = "UserThrustCurves"; - public static final String CONFIRM_DELETE_SIMULATION = "ConfirmDeleteSimulation"; - public static final String AUTO_RUN_SIMULATIONS = "AutoRunSimulations"; - + public static final String DEFAULT_MACH_NUMBER = "DefaultMachNumber"; // Preferences related to data export public static final String EXPORT_FIELD_SEPARATOR = "ExportFieldSeparator"; @@ -66,6 +66,28 @@ public abstract class Preferences implements ChangeSource { public static final String ROCKET_INFO_FONT_SIZE = "RocketInfoFontSize"; + //Preferences Related to Simulations + + public static final String CONFIRM_DELETE_SIMULATION = "ConfirmDeleteSimulation"; + public static final String AUTO_RUN_SIMULATIONS = "AutoRunSimulations"; + public static final String LAUNCH_ROD_LENGTH = "LaunchRodLength"; + public static final String LAUNCH_INTO_WIND = "LaunchIntoWind"; + public static final String LAUNCH_ROD_ANGLE = "LaunchRodAngle"; + public static final String LAUNCH_ROD_DIRECTION = "LaunchRodDirection"; + public static final String WIND_DIRECTION = "WindDirection"; + public static final String WIND_AVERAGE = "WindAverage"; + public static final String WIND_TURBULANCE = "WindTurbulence"; + public static final String LAUNCH_ALTITUDE = "LaunchAltitude"; + public static final String LAUNCH_LATITUDE = "LaunchLatitude"; + public static final String LAUNCH_LONGITUDE = "LaunchLongitude"; + public static final String LAUNCH_TEMPERATURE = "LaunchTemperature"; + public static final String LAUNCH_PRESSURE = "LaunchPressure"; + public static final String LAUNCH_USE_ISA = "LaunchUseISA"; + public static final String SIMULATION_TIME_STEP = "SimulationTimeStep"; + + + private static final AtmosphericModel ISA_ATMOSPHERIC_MODEL = new ExtendedISAModel(); + /* * ****************************************************************************************** * @@ -96,52 +118,297 @@ public abstract class Preferences implements ChangeSource { * @return */ public abstract String getString(String directory, String key, String defaultValue); - + public abstract void putString(String directory, String key, String value); - + /* * ****************************************************************************************** */ public final boolean getCheckUpdates() { return this.getBoolean(CHECK_UPDATES, BuildProperties.getDefaultCheckUpdates()); } - + public final void setCheckUpdates(boolean check) { this.putBoolean(CHECK_UPDATES, check); } - + + public final boolean getConfirmSimDeletion() { + return this.getBoolean(CONFIRM_DELETE_SIMULATION, true); + } + + public final void setConfirmSimDeletion(boolean check) { + this.putBoolean(CONFIRM_DELETE_SIMULATION, check); + } + public final boolean getAutoRunSimulations() { return this.getBoolean(AUTO_RUN_SIMULATIONS, false); } - + public final void setAutoRunSimulations(boolean check) { this.putBoolean(AUTO_RUN_SIMULATIONS, check); } - + + public final boolean getLaunchIntoWind() { + return this.getBoolean(LAUNCH_INTO_WIND, false); + } + + public final void setLaunchIntoWind(boolean check) { + this.putBoolean(LAUNCH_INTO_WIND, check); + } + public final double getDefaultMach() { return Application.getPreferences().getChoice(Preferences.DEFAULT_MACH_NUMBER, 0.9, 0.3); } - + public final void setDefaultMach(double dfn) { double oldDFN = Application.getPreferences().getChoice(Preferences.DEFAULT_MACH_NUMBER, 0.9, 0.3); - + if (MathUtil.equals(oldDFN, dfn)) return; this.putDouble(Preferences.DEFAULT_MACH_NUMBER, dfn); fireChangeEvent(); } - + + public final double getWindTurbulenceIntensity() { + return Application.getPreferences().getChoice(Preferences.WIND_TURBULANCE, 0.9, 0.1); + } + + public final void setWindTurbulenceIntensity(double wti) { + double oldWTI = Application.getPreferences().getChoice(Preferences.WIND_TURBULANCE, 0.9, 0.3); + + if (MathUtil.equals(oldWTI, wti)) + return; + this.putDouble(Preferences.WIND_TURBULANCE, wti); + fireChangeEvent(); + } + + public double getLaunchRodLength() { + return this.getDouble(LAUNCH_ROD_LENGTH, 1); + } + + public void setLaunchRodLength(double launchRodLength) { + if (MathUtil.equals(this.getDouble(LAUNCH_ROD_LENGTH, 1), launchRodLength)) + return; + this.putDouble(LAUNCH_ROD_LENGTH, launchRodLength); + fireChangeEvent(); + } + + + public double getLaunchRodAngle() { + return this.getDouble(LAUNCH_ROD_ANGLE, 0); + } + + public void setLaunchRodAngle(double launchRodAngle) { + launchRodAngle = MathUtil.clamp(launchRodAngle, -Math.PI / 6.0, Math.PI / 6.0); + if (MathUtil.equals(this.getDouble(LAUNCH_ROD_ANGLE, 0), launchRodAngle)) + return; + this.putDouble(LAUNCH_ROD_ANGLE, launchRodAngle); + ; + fireChangeEvent(); + } + + + public double getLaunchRodDirection() { + if (this.getBoolean(LAUNCH_INTO_WIND, true)) { + this.setLaunchRodDirection(this.getDouble(WIND_DIRECTION, Math.PI / 2)); + } + return this.getDouble(WIND_DIRECTION, Math.PI / 2); + } + + public void setLaunchRodDirection(double launchRodDirection) { + launchRodDirection = MathUtil.reduce360(launchRodDirection); + if (MathUtil.equals(this.getDouble(LAUNCH_ROD_DIRECTION, Math.PI / 2.0), launchRodDirection)) + return; + this.putDouble(LAUNCH_ROD_DIRECTION, launchRodDirection); + fireChangeEvent(); + } + + + + public double getWindSpeedAverage() { + return this.getDouble(WIND_AVERAGE, 2); + } + + public void setWindSpeedAverage(double windAverage) { + if (MathUtil.equals(this.getDouble(WIND_AVERAGE, 2), windAverage)) + return; + this.putDouble(WIND_AVERAGE, MathUtil.max(windAverage, 0)); + fireChangeEvent(); + } + + + public double getWindSpeedDeviation() { + return this.getDouble(WIND_AVERAGE, 2) * this.getDouble(WIND_TURBULANCE, .1); + } + + public void setWindSpeedDeviation(double windDeviation) { + double windAverage = this.getDouble(WIND_DIRECTION, 2); + if (windAverage < 0.1) { + windAverage = 0.1; + } + setWindTurbulenceIntensity(windDeviation / windAverage); + } + + public void setWindDirection(double direction) { + direction = MathUtil.reduce360(direction); + if (this.getBoolean(LAUNCH_INTO_WIND, true)) { + this.setLaunchRodDirection(direction); + } + if (MathUtil.equals(this.getDouble(WIND_DIRECTION, Math.PI / 2), direction)) + return; + this.putDouble(WIND_DIRECTION, direction); + fireChangeEvent(); + + } + + public double getWindDirection() { + return this.getDouble(WIND_DIRECTION, Math.PI / 2); + + } + + public double getLaunchAltitude() { + return this.getDouble(LAUNCH_ALTITUDE, 0); + } + + public void setLaunchAltitude(double altitude) { + if (MathUtil.equals(this.getDouble(LAUNCH_ALTITUDE, 0), altitude)) + return; + this.putDouble(LAUNCH_ALTITUDE, altitude); + fireChangeEvent(); + } + + + public double getLaunchLatitude() { + return this.getDouble(LAUNCH_LATITUDE, 28.61); + } + + public void setLaunchLatitude(double launchLatitude) { + launchLatitude = MathUtil.clamp(launchLatitude, -90, 90); + if (MathUtil.equals(this.getDouble(LAUNCH_LATITUDE, 28.61), launchLatitude)) + return; + this.putDouble(LAUNCH_LATITUDE, launchLatitude); + fireChangeEvent(); + } + + public double getLaunchLongitude() { + return this.getDouble(LAUNCH_LONGITUDE, -80.60); + } + + public void setLaunchLongitude(double launchLongitude) { + launchLongitude = MathUtil.clamp(launchLongitude, -180, 180); + if (MathUtil.equals(this.getDouble(LAUNCH_LONGITUDE, -80.60), launchLongitude)) + return; + this.putDouble(LAUNCH_LONGITUDE, launchLongitude); + fireChangeEvent(); + } + + /* + public GeodeticComputationStrategy getGeodeticComputation() { + return geodeticComputation; + } + + public void setGeodeticComputation(GeodeticComputationStrategy geodeticComputation) { + if (this.geodeticComputation == geodeticComputation) + return; + if (geodeticComputation == null) { + throw new IllegalArgumentException("strategy cannot be null"); + } + this.geodeticComputation = geodeticComputation; + fireChangeEvent(); + } + + + public boolean isISAAtmosphere() { + return useISA; + } + + public void setISAAtmosphere(boolean isa) { + if (isa == useISA) + return; + useISA = isa; + fireChangeEvent(); + } + */ + + public double getLaunchTemperature() { + return this.getDouble(LAUNCH_TEMPERATURE, ExtendedISAModel.STANDARD_TEMPERATURE); + } + + + + public void setLaunchTemperature(double launchTemperature) { + if (MathUtil.equals(this.getDouble(LAUNCH_TEMPERATURE, ExtendedISAModel.STANDARD_TEMPERATURE), launchTemperature)) + return; + this.putDouble(LAUNCH_TEMPERATURE, launchTemperature); + fireChangeEvent(); + } + + + + public double getLaunchPressure() { + return this.getDouble(LAUNCH_PRESSURE, ExtendedISAModel.STANDARD_PRESSURE); + } + + + + public void setLaunchPressure(double launchPressure) { + if (MathUtil.equals(this.getDouble(LAUNCH_PRESSURE, ExtendedISAModel.STANDARD_PRESSURE), launchPressure)) + return; + this.putDouble(LAUNCH_PRESSURE, launchPressure); + fireChangeEvent(); + } + + + public boolean getISAAtmosphere() { + return this.getBoolean(LAUNCH_USE_ISA, true); + } + + public void setISAAtmosphere(boolean isa) { + if (this.getBoolean(LAUNCH_USE_ISA, true) == isa) { + return; + } + this.putBoolean(LAUNCH_USE_ISA, isa); + fireChangeEvent(); + } + + /** + * Returns an atmospheric model corresponding to the launch conditions. The + * atmospheric models may be shared between different calls. + * + * @return an AtmosphericModel object. + */ + private AtmosphericModel getAtmosphericModel() { + if (this.getBoolean(LAUNCH_USE_ISA, true)) { + return ISA_ATMOSPHERIC_MODEL; + } + return new ExtendedISAModel(getLaunchAltitude(), this.getDouble(LAUNCH_TEMPERATURE, ExtendedISAModel.STANDARD_TEMPERATURE), + this.getDouble(LAUNCH_PRESSURE, ExtendedISAModel.STANDARD_PRESSURE)); + } + + + public double getTimeStep() { + return this.getDouble(this.SIMULATION_TIME_STEP, 0.05); + } + + public void setTimeStep(double timeStep) { + if (MathUtil.equals(this.getDouble(SIMULATION_TIME_STEP, 0.05), timeStep)) + return; + this.putDouble(SIMULATION_TIME_STEP, timeStep); + fireChangeEvent(); + } + + public final float getRocketInfoFontSize() { return (float) (11.0 + 3 * Application.getPreferences().getChoice(Preferences.ROCKET_INFO_FONT_SIZE, 2, 0)); } - + /** * Enable/Disable the auto-opening of the last edited design file on startup. */ public final void setAutoOpenLastDesignOnStartup(boolean enabled) { this.putBoolean(AUTO_OPEN_LAST_DESIGN, enabled); } - + /** * Answer if the auto-opening of the last edited design file on startup is enabled. * @@ -181,7 +448,7 @@ public abstract class Preferences implements ChangeSource { return def; return v; } - + /** * Returns a limited-range double value from the preferences. If the value * in the preferences is negative or greater than max, then the default value @@ -198,8 +465,8 @@ public abstract class Preferences implements ChangeSource { return def; return v; } - - + + /** * Helper method that puts an integer choice value into the preferences. * @@ -209,7 +476,7 @@ public abstract class Preferences implements ChangeSource { public final void putChoice(String key, int value) { this.putInt(key, value); } - + /** * Retrieve an enum value from the user preferences. * @@ -222,19 +489,19 @@ public abstract class Preferences implements ChangeSource { if (def == null) { throw new BugException("Default value cannot be null"); } - + String value = getString(key, null); if (value == null) { return def; } - + try { return Enum.valueOf(def.getDeclaringClass(), value); } catch (IllegalArgumentException e) { return def; } } - + /** * Store an enum value to the user preferences. * @@ -248,12 +515,12 @@ public abstract class Preferences implements ChangeSource { putString(key, value.name()); } } - + public Color getDefaultColor(Class c) { String color = get("componentColors", c, StaticFieldHolder.DEFAULT_COLORS); if (color == null) return Color.BLACK; - + Color clr = parseColor(color); if (clr != null) { return clr; @@ -261,14 +528,14 @@ public abstract class Preferences implements ChangeSource { return Color.BLACK; } } - + public final void setDefaultColor(Class c, Color color) { if (color == null) return; putString("componentColors", c.getSimpleName(), stringifyColor(color)); } - - + + /** * Retrieve a Line style for the given component. * @param c @@ -282,7 +549,7 @@ public abstract class Preferences implements ChangeSource { return LineStyle.SOLID; } } - + /** * Set a default line style for the given component. * @param c @@ -294,7 +561,7 @@ public abstract class Preferences implements ChangeSource { return; putString("componentStyle", c.getSimpleName(), style.name()); } - + /** * Get the default material type for the given component. * @param componentClass @@ -304,7 +571,7 @@ public abstract class Preferences implements ChangeSource { public Material getDefaultComponentMaterial( Class componentClass, Material.Type type) { - + String material = get("componentMaterials", componentClass, null); if (material != null) { try { @@ -314,7 +581,7 @@ public abstract class Preferences implements ChangeSource { } catch (IllegalArgumentException ignore) { } } - + switch (type) { case LINE: return StaticFieldHolder.DEFAULT_LINE_MATERIAL; @@ -325,7 +592,7 @@ public abstract class Preferences implements ChangeSource { } throw new IllegalArgumentException("Unknown material type: " + type); } - + /** * Set the default material for a component type. * @param componentClass @@ -333,11 +600,11 @@ public abstract class Preferences implements ChangeSource { */ public void setDefaultComponentMaterial( Class componentClass, Material material) { - + putString("componentMaterials", componentClass.getSimpleName(), material == null ? null : material.toStorableString()); } - + /** * get a net.sf.openrocket.util.Color object for the given key. * @param key @@ -351,7 +618,7 @@ public abstract class Preferences implements ChangeSource { } return c; } - + /** * set a net.sf.openrocket.util.Color preference value for the given key. * @param key @@ -360,7 +627,7 @@ public abstract class Preferences implements ChangeSource { public final void putColor(String key, Color value) { putString(key, stringifyColor(value)); } - + /** * Helper function to convert a string representation into a net.sf.openrocket.util.Color object. * @param color @@ -370,7 +637,7 @@ public abstract class Preferences implements ChangeSource { if (color == null) { return null; } - + String[] rgb = color.split(","); if (rgb.length == 3) { try { @@ -383,7 +650,7 @@ public abstract class Preferences implements ChangeSource { } return null; } - + /** * Helper function to convert a net.sf.openrocket.util.Color object into a * String before storing in a preference. @@ -394,7 +661,7 @@ public abstract class Preferences implements ChangeSource { String string = color.getRed() + "," + color.getGreen() + "," + color.getBlue(); return string; } - + /** * Special helper function which allows for a map of default values. * @@ -470,22 +737,22 @@ public abstract class Preferences implements ChangeSource { DEFAULT_COLORS.put(RecoveryDevice.class, "255,0,0"); } } - + private List listeners = new ArrayList(); private final EventObject event = new EventObject(this); - + @Override public void addChangeListener(StateChangeListener listener) { listeners.add(listener); } - + @Override public void removeChangeListener(StateChangeListener listener) { listeners.remove(listener); } - + private void fireChangeEvent() { - + // Copy the list before iterating to prevent concurrent modification exceptions. EventListener[] list = listeners.toArray(new EventListener[0]); for (EventListener l : list) { diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java new file mode 100644 index 000000000..cd6992c4d --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/DesignPreferencesPanel.java @@ -0,0 +1,80 @@ +package net.sf.openrocket.gui.dialogs.preferences; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JSpinner; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.DoubleModel; +import net.sf.openrocket.startup.Preferences; +import net.sf.openrocket.unit.UnitGroup; + +public class DesignPreferencesPanel extends PreferencesPanel { + + public DesignPreferencesPanel() { + super(new MigLayout("fillx, ins 30lp n n n")); + + //// Position to insert new body components: + this.add(new JLabel(trans.get("pref.dlg.lbl.Positiontoinsert")), "gapright para"); + this.add(new JComboBox(new PrefChoiceSelector(Preferences.BODY_COMPONENT_INSERT_POSITION_KEY, + //// Always ask + //// Insert in middle + //// Add to end + trans.get("pref.dlg.PrefChoiseSelector1"), + trans.get("pref.dlg.PrefChoiseSelector2"), + trans.get("pref.dlg.PrefChoiseSelector3"))), "wrap para, growx, sg combos"); + + //// Font size of information in panel window + this.add(new JLabel(trans.get("pref.dlg.lbl.Rocketinfofontsize")), "gapright para"); + + this.add(new JComboBox(new PrefChoiceSelector(Preferences.ROCKET_INFO_FONT_SIZE, + //// Small + //// Medium + //// Large + trans.get("pref.dlg.PrefFontSmall"), + trans.get("pref.dlg.PrefFontMedium"), + trans.get("pref.dlg.PrefFontLarge"))), "wrap para, growx, sg combos"); + + //// Default Mach number + JLabel dfn = new JLabel(trans.get("pref.dlg.lbl.DefaultMach")); + this.add(dfn, "gapright para"); + dfn.setToolTipText(trans.get("pref.dlg.ttip.DefaultMach1")+ + trans.get("pref.dlg.ttip.DefaultMach2")); + + DoubleModel m = new DoubleModel(preferences, "DefaultMach", 1.0, UnitGroup.UNITS_COEFFICIENT, 0.1, 0.9); + + JSpinner spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(trans.get("pref.dlg.ttip.DefaultMach1")+ + trans.get("pref.dlg.ttip.DefaultMach2")); + this.add(spin, "wrap"); + + final JCheckBox autoOpenDesignFile = new JCheckBox(trans.get("pref.dlg.but.openlast")); + autoOpenDesignFile.setSelected(preferences.isAutoOpenLastDesignOnStartupEnabled()); + autoOpenDesignFile.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.setAutoOpenLastDesignOnStartup(autoOpenDesignFile.isSelected()); + } + }); + this.add(autoOpenDesignFile, "wrap, growx, span 2"); + + //// Update flight estimates in the design window + final JCheckBox updateEstimates = + new JCheckBox(trans.get("pref.dlg.checkbox.Updateestimates")); + updateEstimates.setSelected(preferences.computeFlightInBackground()); + updateEstimates.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.setComputeFlightInBackground(updateEstimates.isSelected()); + } + }); + this.add(updateEstimates, "wrap, growx, sg combos "); + + } +} diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/ColorDefaultsPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/DisplayPreferencesPanel.java similarity index 66% rename from swing/src/net/sf/openrocket/gui/dialogs/preferences/ColorDefaultsPanel.java rename to swing/src/net/sf/openrocket/gui/dialogs/preferences/DisplayPreferencesPanel.java index 3fe690a84..8ac52dc4b 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/ColorDefaultsPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/DisplayPreferencesPanel.java @@ -11,8 +11,8 @@ import net.miginfocom.swing.MigLayout; * @author cpearls * */ -public class ColorDefaultsPanel extends JPanel { - public ColorDefaultsPanel(){ +public class DisplayPreferencesPanel extends PreferencesPanel { + public DisplayPreferencesPanel(){ super(new MigLayout("fillx")); } } diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java new file mode 100644 index 000000000..607b42cbf --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GeneralPreferencesPanel.java @@ -0,0 +1,293 @@ +package net.sf.openrocket.gui.dialogs.preferences; + +import java.awt.Dialog.ModalityType; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.JTextField; +import javax.swing.Timer; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.communication.UpdateInfo; +import net.sf.openrocket.communication.UpdateInfoRetriever; +import net.sf.openrocket.gui.components.DescriptionArea; +import net.sf.openrocket.gui.components.StyledLabel; +import net.sf.openrocket.gui.components.StyledLabel.Style; +import net.sf.openrocket.gui.dialogs.UpdateInfoDialog; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.gui.util.SimpleFileFilter; +import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.l10n.L10N; +import net.sf.openrocket.logging.Markers; +import net.sf.openrocket.startup.Preferences; +import net.sf.openrocket.util.BuildProperties; +import net.sf.openrocket.util.Named; +import net.sf.openrocket.util.Utils; + +public class GeneralPreferencesPanel extends PreferencesPanel { + + public GeneralPreferencesPanel(JDialog parent) { + super(parent, new MigLayout("fillx, ins 30lp n n n")); + + + //// Language selector + Locale userLocale = null; + { + String locale = preferences.getString("locale", null); + userLocale = L10N.toLocale(locale); + } + List> locales = new ArrayList>(); + for (Locale l : SwingPreferences.getSupportedLocales()) { + locales.add(new Named(l, l.getDisplayLanguage(l) + "/" + l.getDisplayLanguage())); + } + Collections.sort(locales); + locales.add(0, new Named(null, trans.get("generalprefs.languages.default"))); + + final JComboBox languageCombo = new JComboBox(locales.toArray()); + for (int i = 0; i < locales.size(); i++) { + if (Utils.equals(userLocale, locales.get(i).get())) { + languageCombo.setSelectedIndex(i); + } + } + languageCombo.addActionListener(new ActionListener() { + @Override + @SuppressWarnings("unchecked") + public void actionPerformed(ActionEvent e) { + Named selection = (Named) languageCombo.getSelectedItem(); + Locale l = selection.get(); + preferences.putString(Preferences.USER_LOCAL, l == null ? null : l.toString()); + } + }); + this.add(new JLabel(trans.get("generalprefs.lbl.language")), "gapright para"); + this.add(languageCombo, "wrap rel, growx, sg combos"); + + this.add(new StyledLabel(trans.get("generalprefs.lbl.languageEffect"), -3, Style.ITALIC), "span, wrap para*2"); + + //// User-defined thrust curves: + this.add(new JLabel(trans.get("pref.dlg.lbl.User-definedthrust")), "spanx, wrap"); + final JTextField field = new JTextField(); + List files = preferences.getUserThrustCurveFiles(); + String str = ""; + for (File file : files) { + if (str.length() > 0) { + str += ";"; + } + str += file.getAbsolutePath(); + } + field.setText(str); + field.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void removeUpdate(DocumentEvent e) { + changed(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + changed(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + changed(); + } + + private void changed() { + String text = field.getText(); + List list = new ArrayList(); + for (String s : text.split(";")) { + s = s.trim(); + if (s.length() > 0) { + list.add(new File(s)); + } + } + preferences.setUserThrustCurveFiles(list); + } + }); + this.add(field, "w 100px, gapright unrel, spanx, growx, split"); + + //// Add button + JButton button = new JButton(trans.get("pref.dlg.but.add")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser chooser = new JFileChooser(); + SimpleFileFilter filter = + new SimpleFileFilter( + //// All thrust curve files (*.eng; *.rse; *.zip; directories) + trans.get("pref.dlg.Allthrustcurvefiles"), + true, "eng", "rse", "zip"); + chooser.addChoosableFileFilter(filter); + //// RASP motor files (*.eng) + chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.RASPfiles"), + true, "eng")); + //// RockSim engine files (*.rse) + chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.RockSimfiles"), + true, "rse")); + //// ZIP archives (*.zip) + chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.ZIParchives"), + true, "zip")); + chooser.setFileFilter(filter); + chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + if (defaultDirectory != null) { + chooser.setCurrentDirectory(defaultDirectory); + } + + //// Add + int returnVal = chooser.showDialog(GeneralPreferencesPanel.this, trans.get("pref.dlg.Add")); + if (returnVal == JFileChooser.APPROVE_OPTION) { + log.info(Markers.USER_MARKER, "Adding user thrust curve: " + chooser.getSelectedFile()); + defaultDirectory = chooser.getCurrentDirectory(); + String text = field.getText().trim(); + if (text.length() > 0) { + text += ";"; + } + text += chooser.getSelectedFile().getAbsolutePath(); + field.setText(text); + } + } + }); + this.add(button, "gapright unrel"); + + //// Reset button + button = new JButton(trans.get("pref.dlg.but.reset")); + + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // First one sets to the default, but does not un-set the pref + field.setText(preferences.getDefaultUserThrustCurveFile().getAbsolutePath()); + preferences.setUserThrustCurveFiles(null); + } + }); + this.add(button, "wrap"); + + //// Add directories, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external thrust curves. Changes will take effect the next time you start OpenRocket. + DescriptionArea desc = new DescriptionArea(trans.get("pref.dlg.DescriptionArea.Adddirectories"), 3, -3, false); + desc.setBackground(getBackground()); + this.add(desc, "spanx, growx, wrap 40lp"); + + + + + //// Check for software updates at startup + final JCheckBox softwareUpdateBox = + new JCheckBox(trans.get("pref.dlg.checkbox.Checkupdates")); + softwareUpdateBox.setSelected(preferences.getCheckUpdates()); + softwareUpdateBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.setCheckUpdates(softwareUpdateBox.isSelected()); + } + }); + this.add(softwareUpdateBox); + + //// Check now button + button = new JButton(trans.get("pref.dlg.but.checknow")); + //// Check for software updates now + button.setToolTipText(trans.get("pref.dlg.ttip.Checkupdatesnow")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + checkForUpdates(); + } + }); + this.add(button, "right, wrap"); + } + + + private void checkForUpdates() { + final UpdateInfoRetriever retriever = new UpdateInfoRetriever(); + retriever.start(); + + + // Progress dialog + final JDialog dialog1 = new JDialog(this.parentDialog, ModalityType.APPLICATION_MODAL); + JPanel panel = new JPanel(new MigLayout()); + + //// Checking for updates... + panel.add(new JLabel(trans.get("pref.dlg.lbl.Checkingupdates")), "wrap"); + + JProgressBar bar = new JProgressBar(); + bar.setIndeterminate(true); + panel.add(bar, "growx, wrap para"); + + //// Cancel button + JButton cancel = new JButton(trans.get("dlg.but.cancel")); + cancel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + dialog1.dispose(); + } + }); + panel.add(cancel, "right"); + dialog1.add(panel); + + GUIUtil.setDisposableDialogOptions(dialog1, cancel); + + + // Timer to monitor progress + final Timer timer = new Timer(100, null); + final long startTime = System.currentTimeMillis(); + + ActionListener listener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (!retriever.isRunning() || startTime + 10000 < System.currentTimeMillis()) { + timer.stop(); + dialog1.dispose(); + } + } + }; + timer.addActionListener(listener); + timer.start(); + + + // Wait for action + dialog1.setVisible(true); + + + // Check result + UpdateInfo info = retriever.getUpdateInfo(); + if (info == null) { + JOptionPane.showMessageDialog(this, + //// An error occurred while communicating with the server. + trans.get("pref.dlg.lbl.msg1"), + //// Unable to retrieve update information + trans.get("pref.dlg.lbl.msg2"), JOptionPane.WARNING_MESSAGE, null); + } else if (info.getLatestVersion() == null || + info.getLatestVersion().equals("") || + BuildProperties.getVersion().equalsIgnoreCase(info.getLatestVersion())) { + JOptionPane.showMessageDialog(this, + //// You are running the latest version of OpenRocket. + trans.get("pref.dlg.lbl.msg3"), + //// No updates available + trans.get("pref.dlg.lbl.msg4"), JOptionPane.INFORMATION_MESSAGE, null); + } else { + UpdateInfoDialog infoDialog = new UpdateInfoDialog(info); + infoDialog.setVisible(true); + if (infoDialog.isReminderSelected()) { + preferences.putString(SwingPreferences.LAST_UPDATE, ""); + } else { + preferences.putString(SwingPreferences.LAST_UPDATE, info.getLatestVersion()); + } + } + + } + +} diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/GraphicsPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GraphicsPreferencesPanel.java new file mode 100644 index 000000000..c51c7b16a --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/GraphicsPreferencesPanel.java @@ -0,0 +1,186 @@ +package net.sf.openrocket.gui.dialogs.preferences; + +import java.awt.Desktop; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.border.TitledBorder; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.gui.adaptors.BooleanModel; +import net.sf.openrocket.gui.components.StyledLabel; +import net.sf.openrocket.gui.components.StyledLabel.Style; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.startup.Preferences; + +import com.itextpdf.text.Font; + +public class GraphicsPreferencesPanel extends PreferencesPanel { + + public GraphicsPreferencesPanel(JDialog parent) { + super(parent, new MigLayout("fillx")); + + this.add(new JPanel(new MigLayout("fill, ins n n n")) { + { //Editor Options + TitledBorder border = BorderFactory.createTitledBorder(trans.get("pref.dlg.lbl.DecalEditor")); + GUIUtil.changeFontStyle(border, Font.BOLD); + setBorder(border); + + ButtonGroup execGroup = new ButtonGroup(); + + JRadioButton showPrompt = new JRadioButton(trans.get("EditDecalDialog.lbl.prompt")); + showPrompt.setSelected(!preferences.isDecalEditorPreferenceSet()); + showPrompt.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (((JRadioButton) e.getItem()).isSelected()) { + preferences.clearDecalEditorPreference(); + } + } + }); + add(showPrompt, "wrap"); + execGroup.add(showPrompt); + + if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) { + + JRadioButton systemRadio = new JRadioButton(trans.get("EditDecalDialog.lbl.system")); + systemRadio.setSelected(preferences.isDecalEditorPreferenceSystem()); + systemRadio.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (((JRadioButton) e.getItem()).isSelected()) { + preferences.setDecalEditorPreference(true, null); + } + } + }); + add(systemRadio, "wrap"); + execGroup.add(systemRadio); + + } + + boolean commandLineIsSelected = preferences.isDecalEditorPreferenceSet() && !preferences.isDecalEditorPreferenceSystem(); + final JRadioButton commandRadio = new JRadioButton(trans.get("EditDecalDialog.lbl.cmdline")); + commandRadio.setSelected(commandLineIsSelected); + add(commandRadio, "wrap"); + execGroup.add(commandRadio); + + final JTextField commandText = new JTextField(); + commandText.setEnabled(commandLineIsSelected); + commandText.setText(commandLineIsSelected ? preferences.getDecalEditorCommandLine() : ""); + commandText.getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void insertUpdate(DocumentEvent e) { + preferences.setDecalEditorPreference(false, commandText.getText()); + } + + @Override + public void removeUpdate(DocumentEvent e) { + preferences.setDecalEditorPreference(false, commandText.getText()); + } + + @Override + public void changedUpdate(DocumentEvent e) { + preferences.setDecalEditorPreference(false, commandText.getText()); + } + + }); + add(commandText, "growx, wrap"); + + final JButton chooser = new JButton(trans.get("EditDecalDialog.btn.chooser")); + chooser.setEnabled(commandLineIsSelected); + chooser.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser fc = new JFileChooser(); + int action = fc.showOpenDialog(SwingUtilities.windowForComponent(GraphicsPreferencesPanel.this.parentDialog)); + if (action == JFileChooser.APPROVE_OPTION) { + String commandLine = fc.getSelectedFile().getAbsolutePath(); + commandText.setText(commandLine); + preferences.setDecalEditorPreference(false, commandLine); + } + + } + + }); + add(chooser, "wrap"); + + + commandRadio.addChangeListener(new ChangeListener() { + + @Override + public void stateChanged(ChangeEvent e) { + boolean enabled = commandRadio.isSelected(); + commandText.setEnabled(enabled); + chooser.setEnabled(enabled); + } + + }); + } + }, "growx, span"); + + this.add(new JPanel(new MigLayout("fill, ins n n n")) { + {/////GL Options + TitledBorder border = BorderFactory.createTitledBorder(trans.get("pref.dlg.opengl.lbl.title")); + GUIUtil.changeFontStyle(border, Font.BOLD); + setBorder(border); + + //// The effects will take place the next time you open a window. + add(new StyledLabel( + trans.get("pref.dlg.lbl.effect1"), -2, Style.ITALIC), + "spanx, wrap"); + + BooleanModel enableGLModel = new BooleanModel(preferences.getBoolean(Preferences.OPENGL_ENABLED, true)); + final JCheckBox enableGL = new JCheckBox(enableGLModel); + enableGL.setText(trans.get("pref.dlg.opengl.but.enableGL")); + enableGL.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.putBoolean(Preferences.OPENGL_ENABLED, enableGL.isSelected()); + } + }); + add(enableGL, "wrap"); + + final JCheckBox enableAA = new JCheckBox(trans.get("pref.dlg.opengl.but.enableAA")); + enableAA.setSelected(preferences.getBoolean(Preferences.OPENGL_ENABLE_AA, true)); + enableAA.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.putBoolean(Preferences.OPENGL_ENABLE_AA, enableAA.isSelected()); + } + }); + enableGLModel.addEnableComponent(enableAA); + add(enableAA, "wrap"); + + final JCheckBox useFBO = new JCheckBox(trans.get("pref.dlg.opengl.lbl.useFBO")); + useFBO.setSelected(preferences.getBoolean(Preferences.OPENGL_USE_FBO, false)); + useFBO.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.putBoolean(Preferences.OPENGL_USE_FBO, useFBO.isSelected()); + } + }); + enableGLModel.addEnableComponent(useFBO); + add(useFBO, "wrap"); + } + }, "growx, span"); + } + +} diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/LaunchPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/LaunchPreferencesPanel.java new file mode 100644 index 000000000..5553737ca --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/LaunchPreferencesPanel.java @@ -0,0 +1,448 @@ +package net.sf.openrocket.gui.dialogs.preferences; + +import java.awt.LayoutManager; + +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.BooleanModel; +import net.sf.openrocket.gui.adaptors.DoubleModel; +import net.sf.openrocket.gui.components.BasicSlider; +import net.sf.openrocket.gui.components.UnitSelector; +import net.sf.openrocket.models.atmosphere.ExtendedISAModel; +import net.sf.openrocket.simulation.SimulationOptions; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.Chars; + +public class LaunchPreferencesPanel extends PreferencesPanel { + + public LaunchPreferencesPanel(JDialog parent, LayoutManager layout) { + super(parent, layout); + // TODO Auto-generated constructor stub + } + + public LaunchPreferencesPanel() { + super(new MigLayout("fillx, ins 30lp n n n")); + + JPanel sub; + String tip; + UnitSelector unit; + BasicSlider slider; + DoubleModel m; + JSpinner spin; + + // Wind settings: Average wind speed, turbulence intensity, std. + // deviation, and direction + sub = new JPanel(new MigLayout("fill, gap rel unrel", + "[grow][65lp!][30lp!][75lp!]", "")); + // Wind + sub.setBorder(BorderFactory.createTitledBorder(trans + .get("simedtdlg.lbl.Wind"))); + this.add(sub, "growx, split 2, aligny 0, flowy, gapright para"); + + // Wind average + // Average windspeed: + JLabel label = new JLabel(trans.get("simedtdlg.lbl.Averwindspeed")); + // The average windspeed relative to the ground. + tip = trans.get("simedtdlg.lbl.ttip.Averwindspeed"); + label.setToolTipText(tip); + sub.add(label); + + m = new DoubleModel(preferences, "WindSpeedAverage", + UnitGroup.UNITS_WINDSPEED, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + sub.add(spin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + sub.add(unit, "growx"); + slider = new BasicSlider(m.getSliderModel(0, 10.0)); + slider.setToolTipText(tip); + sub.add(slider, "w 75lp, wrap"); + + // Wind std. deviation + // // Standard deviation: + label = new JLabel(trans.get("simedtdlg.lbl.Stddeviation")); + // // The standard deviation of the windspeed.
+ // // The windspeed is within twice the standard deviation from the + // average for 95% of the time. + tip = trans.get("simedtdlg.lbl.ttip.Stddeviation"); + label.setToolTipText(tip); + sub.add(label); + + m = new DoubleModel(preferences, "WindSpeedDeviation", + UnitGroup.UNITS_WINDSPEED, 0); + DoubleModel m2 = new DoubleModel(preferences, "WindSpeedAverage", 0.25, + UnitGroup.UNITS_COEFFICIENT, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + sub.add(spin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + sub.add(unit, "growx"); + slider = new BasicSlider(m.getSliderModel(new DoubleModel(0), m2)); + slider.setToolTipText(tip); + sub.add(slider, "w 75lp, wrap"); + + // Wind Direction: + label = new JLabel(trans.get("simedtdlg.lbl.Winddirection")); + // // Direction of the wind. 0 is north + tip = trans.get("simedtdlg.lbl.ttip.Winddirection"); + label.setToolTipText(tip); + sub.add(label); + + m = new DoubleModel(preferences, "WindDirection", 1.0, + UnitGroup.UNITS_ANGLE, 0, 2 * Math.PI); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + sub.add(spin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + sub.add(unit, "growx"); + slider = new BasicSlider(m.getSliderModel(0, 2 * Math.PI)); + slider.setToolTipText(tip); + sub.add(slider, "w 75lp, wrap"); + + // Wind turbulence intensity + // // Turbulence intensity: + label = new JLabel(trans.get("simedtdlg.lbl.Turbulenceintensity")); + // // The turbulence intensity is the standard deviation divided + // by the average windspeed.
+ // // Typical values range from + // // to + tip = trans.get("simedtdlg.lbl.ttip.Turbulenceintensity1") + + trans.get("simedtdlg.lbl.ttip.Turbulenceintensity2") + " " + + UnitGroup.UNITS_RELATIVE.getDefaultUnit().toStringUnit(0.05) + + " " + trans.get("simedtdlg.lbl.ttip.Turbulenceintensity3") + + " " + + UnitGroup.UNITS_RELATIVE.getDefaultUnit().toStringUnit(0.20) + + "."; + label.setToolTipText(tip); + sub.add(label); + + m = new DoubleModel(preferences, "WindTurbulenceIntensity", + UnitGroup.UNITS_RELATIVE, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + sub.add(spin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + sub.add(unit, "growx"); + + final JLabel intensityLabel = new JLabel( + getIntensityDescription(preferences + .getWindTurbulenceIntensity())); + intensityLabel.setToolTipText(tip); + sub.add(intensityLabel, "w 75lp, wrap"); + m.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + intensityLabel.setText(getIntensityDescription(preferences + .getWindTurbulenceIntensity())); + } + }); + + // // Temperature and pressure + sub = new JPanel(new MigLayout("fill, gap rel unrel", + "[grow][65lp!][30lp!][75lp!]", "")); + // // Atmospheric preferences + sub.setBorder(BorderFactory.createTitledBorder(trans + .get("simedtdlg.border.Atmoscond"))); + this.add(sub, "growx, aligny 0, gapright para"); + + BooleanModel isa = new BooleanModel(preferences, "ISAAtmosphere"); + JCheckBox check = new JCheckBox(isa); + // // Use International Standard Atmosphere + check.setText(trans.get("simedtdlg.checkbox.InterStdAtmosphere")); + // // Select to use the International Standard Atmosphere model. + // //
This model has a temperature of + // // and a pressure of + // // at sea level. + check.setToolTipText(trans + .get("simedtdlg.checkbox.ttip.InterStdAtmosphere1") + + " " + + UnitGroup.UNITS_TEMPERATURE + .toStringUnit(ExtendedISAModel.STANDARD_TEMPERATURE) + + " " + + trans.get("simedtdlg.checkbox.ttip.InterStdAtmosphere2") + + " " + + UnitGroup.UNITS_PRESSURE + .toStringUnit(ExtendedISAModel.STANDARD_PRESSURE) + + " " + + trans.get("simedtdlg.checkbox.ttip.InterStdAtmosphere3")); + sub.add(check, "spanx, wrap unrel"); + + // Temperature: + label = new JLabel(trans.get("simedtdlg.lbl.Temperature")); + // // The temperature at the launch site. + tip = trans.get("simedtdlg.lbl.ttip.Temperature"); + label.setToolTipText(tip); + isa.addEnableComponent(label, false); + sub.add(label); + + m = new DoubleModel(preferences, "LaunchTemperature", + UnitGroup.UNITS_TEMPERATURE, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + isa.addEnableComponent(spin, false); + sub.add(spin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + isa.addEnableComponent(unit, false); + sub.add(unit, "growx"); + slider = new BasicSlider(m.getSliderModel(253.15, 308.15)); // -20 ... + // 35 + slider.setToolTipText(tip); + isa.addEnableComponent(slider, false); + sub.add(slider, "w 75lp, wrap"); + + // Pressure: + label = new JLabel(trans.get("simedtdlg.lbl.Pressure")); + // // The atmospheric pressure at the launch site. + tip = trans.get("simedtdlg.lbl.ttip.Pressure"); + label.setToolTipText(tip); + isa.addEnableComponent(label, false); + sub.add(label); + + m = new DoubleModel(preferences, "LaunchPressure", + UnitGroup.UNITS_PRESSURE, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + isa.addEnableComponent(spin, false); + sub.add(spin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + isa.addEnableComponent(unit, false); + sub.add(unit, "growx"); + slider = new BasicSlider(m.getSliderModel(0.950e5, 1.050e5)); + slider.setToolTipText(tip); + isa.addEnableComponent(slider, false); + sub.add(slider, "w 75lp, wrap"); + + // // Launch site preferences + sub = new JPanel(new MigLayout("fill, gap rel unrel", + "[grow][65lp!][30lp!][75lp!]", "")); + // // Launch site + sub.setBorder(BorderFactory.createTitledBorder(trans + .get("simedtdlg.lbl.Launchsite"))); + this.add(sub, "growx, split 2, aligny 0, flowy"); + + // Latitude: + label = new JLabel(trans.get("simedtdlg.lbl.Latitude")); + // // The launch site latitude affects the gravitational pull of + // Earth.
+ // // Positive values are on the Northern hemisphere, negative values on + // the Southern hemisphere. + tip = trans.get("simedtdlg.lbl.ttip.Latitude"); + label.setToolTipText(tip); + sub.add(label); + + m = new DoubleModel(preferences, "LaunchLatitude", + UnitGroup.UNITS_NONE, -90, 90); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + sub.add(spin, "w 65lp!"); + + label = new JLabel(Chars.DEGREE + " N"); + label.setToolTipText(tip); + sub.add(label, "growx"); + slider = new BasicSlider(m.getSliderModel(-90, 90)); + slider.setToolTipText(tip); + sub.add(slider, "w 75lp, wrap"); + + // Longitude: + label = new JLabel(trans.get("simedtdlg.lbl.Longitude")); + tip = trans.get("simedtdlg.lbl.ttip.Longitude"); + label.setToolTipText(tip); + sub.add(label); + + m = new DoubleModel(preferences, "LaunchLongitude", + UnitGroup.UNITS_NONE, -180, 180); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + sub.add(spin, "w 65lp!"); + + label = new JLabel(Chars.DEGREE + " E"); + label.setToolTipText(tip); + sub.add(label, "growx"); + slider = new BasicSlider(m.getSliderModel(-180, 180)); + slider.setToolTipText(tip); + sub.add(slider, "w 75lp, wrap"); + + // Altitude: + label = new JLabel(trans.get("simedtdlg.lbl.Altitude")); + // // The launch altitude above mean sea level.
+ // // This affects the position of the rocket in the atmospheric model. + tip = trans.get("simedtdlg.lbl.ttip.Altitude"); + label.setToolTipText(tip); + sub.add(label); + + m = new DoubleModel(preferences, "LaunchAltitude", + UnitGroup.UNITS_DISTANCE, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + sub.add(spin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + sub.add(unit, "growx"); + slider = new BasicSlider(m.getSliderModel(0, 250, 1000)); + slider.setToolTipText(tip); + sub.add(slider, "w 75lp, wrap"); + + // // Launch rod + sub = new JPanel(new MigLayout("fill, gap rel unrel", + "[grow][65lp!][30lp!][75lp!]", "")); + // // Launch rod + sub.setBorder(BorderFactory.createTitledBorder(trans + .get("simedtdlg.border.Launchrod"))); + this.add(sub, "growx, aligny 0, wrap"); + + // Length: + label = new JLabel(trans.get("simedtdlg.lbl.Length")); + // // The length of the launch rod. + tip = trans.get("simedtdlg.lbl.ttip.Length"); + label.setToolTipText(tip); + sub.add(label); + + m = new DoubleModel(preferences, "LaunchRodLength", + UnitGroup.UNITS_LENGTH, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + sub.add(spin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + sub.add(unit, "growx"); + slider = new BasicSlider(m.getSliderModel(0, 1, 5)); + slider.setToolTipText(tip); + sub.add(slider, "w 75lp, wrap"); + + // Keep launch rod parallel to the wind. + + BooleanModel intoWind = new BooleanModel(preferences, "LaunchIntoWind"); + JCheckBox checkWind = new JCheckBox(intoWind); + // // Use International Standard Atmosphere + checkWind.setText(trans.get("simedtdlg.checkbox.Intowind")); + checkWind.setToolTipText(trans.get("simedtdlg.checkbox.ttip.Intowind1") + + trans.get("simedtdlg.checkbox.ttip.Intowind2") + + trans.get("simedtdlg.checkbox.ttip.Intowind3") + + trans.get("simedtdlg.checkbox.ttip.Intowind4")); + sub.add(checkWind, "spanx, wrap unrel"); + + // Angle: + label = new JLabel(trans.get("simedtdlg.lbl.Angle")); + // // The angle of the launch rod from vertical. + tip = trans.get("simedtdlg.lbl.ttip.Angle"); + label.setToolTipText(tip); + sub.add(label); + + m = new DoubleModel(preferences, "LaunchRodAngle", + UnitGroup.UNITS_ANGLE, -SimulationOptions.MAX_LAUNCH_ROD_ANGLE, + SimulationOptions.MAX_LAUNCH_ROD_ANGLE); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + spin.setToolTipText(tip); + sub.add(spin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + sub.add(unit, "growx"); + slider = new BasicSlider(m.getSliderModel( + -SimulationOptions.MAX_LAUNCH_ROD_ANGLE, 0, + SimulationOptions.MAX_LAUNCH_ROD_ANGLE)); + slider.setToolTipText(tip); + sub.add(slider, "w 75lp, wrap"); + + // Direction: + JLabel directionLabel = new JLabel(trans.get("simedtdlg.lbl.Direction")); + // // Direction of the launch rod. + tip = trans.get("simedtdlg.lbl.ttip.Direction1") + + UnitGroup.UNITS_ANGLE.toStringUnit(0) + " " + + trans.get("simedtdlg.lbl.ttip.Direction2") + " " + + UnitGroup.UNITS_ANGLE.toStringUnit(2 * Math.PI) + " " + + trans.get("simedtdlg.lbl.ttip.Direction3"); + directionLabel.setToolTipText(tip); + sub.add(directionLabel); + + m = new DoubleModel(preferences, "LaunchRodDirection", 1.0, + UnitGroup.UNITS_ANGLE, 0, 2 * Math.PI); + + JSpinner directionSpin = new JSpinner(m.getSpinnerModel()); + directionSpin.setEditor(new SpinnerEditor(directionSpin)); + directionSpin.setToolTipText(tip); + sub.add(directionSpin, "w 65lp!"); + + unit = new UnitSelector(m); + unit.setToolTipText(tip); + sub.add(unit, "growx"); + BasicSlider directionSlider = new BasicSlider(m.getSliderModel(0, + 2 * Math.PI)); + directionSlider.setToolTipText(tip); + sub.add(directionSlider, "w 75lp, wrap"); + intoWind.addEnableComponent(directionLabel, false); + intoWind.addEnableComponent(directionSpin, false); + intoWind.addEnableComponent(unit, false); + intoWind.addEnableComponent(directionSlider, false); + + } + + private String getIntensityDescription(double i) { + if (i < 0.001) + // // None + return trans.get("simedtdlg.IntensityDesc.None"); + if (i < 0.05) + // // Very low + return trans.get("simedtdlg.IntensityDesc.Verylow"); + if (i < 0.10) + // // Low + return trans.get("simedtdlg.IntensityDesc.Low"); + if (i < 0.15) + // // Medium + return trans.get("simedtdlg.IntensityDesc.Medium"); + if (i < 0.20) + // // High + return trans.get("simedtdlg.IntensityDesc.High"); + if (i < 0.25) + // // Very high + return trans.get("simedtdlg.IntensityDesc.Veryhigh"); + // // Extreme + return trans.get("simedtdlg.IntensityDesc.Extreme"); + } + +} diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java index 6ada88270..cc68b3879 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java @@ -1,115 +1,78 @@ package net.sf.openrocket.gui.dialogs.preferences; -import java.awt.Desktop; import java.awt.Dialog; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import javax.swing.AbstractListModel; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.ComboBoxModel; import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JPanel; -import javax.swing.JProgressBar; -import javax.swing.JRadioButton; -import javax.swing.JSpinner; import javax.swing.JTabbedPane; -import javax.swing.JTextField; -import javax.swing.SwingUtilities; -import javax.swing.Timer; -import javax.swing.border.TitledBorder; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.communication.UpdateInfo; -import net.sf.openrocket.communication.UpdateInfoRetriever; -import net.sf.openrocket.gui.SpinnerEditor; -import net.sf.openrocket.gui.adaptors.BooleanModel; -import net.sf.openrocket.gui.adaptors.DoubleModel; -import net.sf.openrocket.gui.components.DescriptionArea; -import net.sf.openrocket.gui.components.StyledLabel; -import net.sf.openrocket.gui.components.StyledLabel.Style; -import net.sf.openrocket.gui.dialogs.UpdateInfoDialog; import net.sf.openrocket.gui.util.GUIUtil; -import net.sf.openrocket.gui.util.SimpleFileFilter; import net.sf.openrocket.gui.util.SwingPreferences; -import net.sf.openrocket.l10n.L10N; import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.logging.Markers; import net.sf.openrocket.startup.Application; -import net.sf.openrocket.startup.Preferences; -import net.sf.openrocket.unit.Unit; -import net.sf.openrocket.unit.UnitGroup; -import net.sf.openrocket.util.BuildProperties; -import net.sf.openrocket.util.Named; -import net.sf.openrocket.util.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.itextpdf.text.Font; - - public class PreferencesDialog extends JDialog { - private static final Logger log = LoggerFactory.getLogger(PreferencesDialog.class); - - private final List unitSelectors = new ArrayList(); - + private static final Logger log = LoggerFactory + .getLogger(PreferencesDialog.class); + private File defaultDirectory = null; private static final Translator trans = Application.getTranslator(); - - private final SwingPreferences preferences = (SwingPreferences) Application.getPreferences(); - + + private final SwingPreferences preferences = (SwingPreferences) Application + .getPreferences(); + private PreferencesDialog(Window parent) { - //// Preferences - super(parent, trans.get("pref.dlg.title.Preferences"), Dialog.ModalityType.APPLICATION_MODAL); - - JPanel panel = new JPanel(new MigLayout("fill, gap unrel", "[grow]", "[grow][]")); - + // // Preferences + super(parent, trans.get("pref.dlg.title.Preferences"), + Dialog.ModalityType.APPLICATION_MODAL); + + JPanel panel = new JPanel(new MigLayout("fill, gap unrel", "[grow]", + "[grow][]")); + JTabbedPane tabbedPane = new JTabbedPane(); panel.add(tabbedPane, "grow, wrap"); - - //// Options and Miscellaneous options - tabbedPane.addTab(trans.get("pref.dlg.tab.Options"), null, generalOptionsPane(), + + // // Options and Miscellaneous options + tabbedPane.addTab(trans.get("pref.dlg.tab.Options"), null, + new GeneralPreferencesPanel(this), trans.get("pref.dlg.tab.Miscellaneousoptions")); - //// Options and Miscellaneous options - tabbedPane.addTab(trans.get("pref.dlg.tab.Design"), null, designOptionsPane(), + // // Designer options + tabbedPane.addTab(trans.get("pref.dlg.tab.Design"), null, + new DesignPreferencesPanel(), trans.get("pref.dlg.tab.Design")); + // // Simulation options + tabbedPane.addTab(trans.get("pref.dlg.tab.Simulation"), null, + new SimulationPreferencesPanel(), trans.get("pref.dlg.tab.Design")); - //// Options and Miscellaneous options - tabbedPane.addTab(trans.get("pref.dlg.tab.Simulation"), null, simulationOptionsPane(), - trans.get("pref.dlg.tab.Design")); - //// Units and Default units - tabbedPane.addTab(trans.get("pref.dlg.tab.Units"), null, unitsPane(), + // // Launch options + tabbedPane.addTab(trans.get("pref.dlg.tab.Launch"), null, + new LaunchPreferencesPanel(), trans.get("pref.dlg.tab.Launch")); + // // Units and Default units + tabbedPane.addTab(trans.get("pref.dlg.tab.Units"), null, + new UnitsPreferencesPanel(this), trans.get("pref.dlg.tab.Defaultunits")); - //// Materials and Custom materials - tabbedPane.addTab(trans.get("pref.dlg.tab.Materials"), null, new MaterialEditPanel(), + // // Materials and Custom materials + tabbedPane.addTab(trans.get("pref.dlg.tab.Materials"), null, + new MaterialEditPanel(), trans.get("pref.dlg.tab.Custommaterials")); - //// Decal Editor selection - tabbedPane.addTab(trans.get("pref.dlg.tab.Graphics"), graphicsOptionsPane()); - - //// Default Colors Preferences - tabbedPane.addTab(trans.get("pref.dlg.tab.Colors"), colorOptionsPane()); - //// Close button + // // Decal Editor selection + tabbedPane.addTab(trans.get("pref.dlg.tab.Graphics"), + new GraphicsPreferencesPanel(this)); + + // // Default Colors Preferences + tabbedPane.addTab(trans.get("pref.dlg.tab.Colors"), + new DisplayPreferencesPanel()); + // // Close button JButton close = new JButton(trans.get("dlg.but.close")); close.addActionListener(new ActionListener() { @Override @@ -119,841 +82,25 @@ public class PreferencesDialog extends JDialog { } }); panel.add(close, "span, right, tag close"); - + this.setContentPane(panel); pack(); this.setLocationRelativeTo(null); - + this.addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { preferences.storeDefaultUnits(); } }); - + GUIUtil.setDisposableDialogOptions(this, close); } - - private JPanel colorOptionsPane(){ - return new JPanel(new MigLayout("fillx, ins 301p n n n")); - } - - @SuppressWarnings("unchecked") - private JPanel designOptionsPane() { - JPanel panel = new JPanel(new MigLayout("fillx, ins 30lp n n n")); - - //// Position to insert new body components: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Positiontoinsert")), "gapright para"); - panel.add(new JComboBox(new PrefChoiceSelector(Preferences.BODY_COMPONENT_INSERT_POSITION_KEY, - //// Always ask - //// Insert in middle - //// Add to end - trans.get("pref.dlg.PrefChoiseSelector1"), - trans.get("pref.dlg.PrefChoiseSelector2"), - trans.get("pref.dlg.PrefChoiseSelector3"))), "wrap para, growx, sg combos"); - - //// Font size of information in panel window - panel.add(new JLabel(trans.get("pref.dlg.lbl.Rocketinfofontsize")), "gapright para"); - panel.add(new JComboBox(new PrefChoiceSelector(Preferences.ROCKET_INFO_FONT_SIZE, - //// Small - //// Medium - //// Large - trans.get("pref.dlg.PrefFontSmall"), - trans.get("pref.dlg.PrefFontMedium"), - trans.get("pref.dlg.PrefFontLarge"))), "wrap para, growx, sg combos"); - - //// Default Mach number - JLabel dfn = new JLabel(trans.get("pref.dlg.lbl.DefaultMach")); - panel.add(dfn, "gapright para"); - dfn.setToolTipText(trans.get("pref.dlg.ttip.DefaultMach1")+ - trans.get("pref.dlg.ttip.DefaultMach2")); + // ////// Singleton implementation //////// - DoubleModel m = new DoubleModel(preferences, "DefaultMach", 1.0, UnitGroup.UNITS_COEFFICIENT, 0.1, 0.9); - //mach = new DoubleModel(rocketPanel, "CPMach", UnitGroup.UNITS_COEFFICIENT, 0); - - JSpinner spin = new JSpinner(m.getSpinnerModel()); - spin.setEditor(new SpinnerEditor(spin)); - spin.setToolTipText(trans.get("pref.dlg.ttip.DefaultMach1")+ - trans.get("pref.dlg.ttip.DefaultMach2")); - panel.add(spin, "wrap"); - - - /* - panel.add(new JComboBox(new PrefChoiceSelector(Preferences.ROCKET_INFO_FONT_SIZE, - //// Small - //// Medium - //// Large - trans.get("pref.dlg.PrefFontSmall"), - trans.get("pref.dlg.PrefFontMedium"), - trans.get("pref.dlg.PrefFontLarge"))), "wrap 40lp, growx, sg combos"); - */ - final JCheckBox autoOpenDesignFile = new JCheckBox(trans.get("pref.dlg.but.openlast")); - autoOpenDesignFile.setSelected(preferences.isAutoOpenLastDesignOnStartupEnabled()); - autoOpenDesignFile.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - preferences.setAutoOpenLastDesignOnStartup(autoOpenDesignFile.isSelected()); - } - }); - panel.add(autoOpenDesignFile, "wrap, growx, span 2"); - - //// Update flight estimates in the design window - final JCheckBox updateEstimates = - new JCheckBox(trans.get("pref.dlg.checkbox.Updateestimates")); - updateEstimates.setSelected(preferences.computeFlightInBackground()); - updateEstimates.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - preferences.setComputeFlightInBackground(updateEstimates.isSelected()); - } - }); - panel.add(updateEstimates, "wrap, growx, sg combos "); - - return panel; - } - - private JPanel generalOptionsPane() { - JPanel panel = new JPanel(new MigLayout("fillx, ins 30lp n n n")); - - - //// Language selector - Locale userLocale = null; - { - String locale = preferences.getString("locale", null); - userLocale = L10N.toLocale(locale); - } - List> locales = new ArrayList>(); - for (Locale l : SwingPreferences.getSupportedLocales()) { - locales.add(new Named(l, l.getDisplayLanguage(l) + "/" + l.getDisplayLanguage())); - } - Collections.sort(locales); - locales.add(0, new Named(null, trans.get("languages.default"))); - - final JComboBox languageCombo = new JComboBox(locales.toArray()); - for (int i = 0; i < locales.size(); i++) { - if (Utils.equals(userLocale, locales.get(i).get())) { - languageCombo.setSelectedIndex(i); - } - } - languageCombo.addActionListener(new ActionListener() { - @Override - @SuppressWarnings("unchecked") - public void actionPerformed(ActionEvent e) { - Named selection = (Named) languageCombo.getSelectedItem(); - Locale l = selection.get(); - preferences.putString(Preferences.USER_LOCAL, l == null ? null : l.toString()); - } - }); - panel.add(new JLabel(trans.get("lbl.language")), "gapright para"); - panel.add(languageCombo, "wrap rel, growx, sg combos"); - - panel.add(new StyledLabel(trans.get("PreferencesDialog.lbl.languageEffect"), -3, Style.ITALIC), "span, wrap para*2"); - - //// User-defined thrust curves: - panel.add(new JLabel(trans.get("pref.dlg.lbl.User-definedthrust")), "spanx, wrap"); - final JTextField field = new JTextField(); - List files = preferences.getUserThrustCurveFiles(); - String str = ""; - for (File file : files) { - if (str.length() > 0) { - str += ";"; - } - str += file.getAbsolutePath(); - } - field.setText(str); - field.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void removeUpdate(DocumentEvent e) { - changed(); - } - - @Override - public void insertUpdate(DocumentEvent e) { - changed(); - } - - @Override - public void changedUpdate(DocumentEvent e) { - changed(); - } - - private void changed() { - String text = field.getText(); - List list = new ArrayList(); - for (String s : text.split(";")) { - s = s.trim(); - if (s.length() > 0) { - list.add(new File(s)); - } - } - preferences.setUserThrustCurveFiles(list); - } - }); - panel.add(field, "w 100px, gapright unrel, spanx, growx, split"); - - //// Add button - JButton button = new JButton(trans.get("pref.dlg.but.add")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser chooser = new JFileChooser(); - SimpleFileFilter filter = - new SimpleFileFilter( - //// All thrust curve files (*.eng; *.rse; *.zip; directories) - trans.get("pref.dlg.Allthrustcurvefiles"), - true, "eng", "rse", "zip"); - chooser.addChoosableFileFilter(filter); - //// RASP motor files (*.eng) - chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.RASPfiles"), - true, "eng")); - //// RockSim engine files (*.rse) - chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.RockSimfiles"), - true, "rse")); - //// ZIP archives (*.zip) - chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.ZIParchives"), - true, "zip")); - chooser.setFileFilter(filter); - chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - if (defaultDirectory != null) { - chooser.setCurrentDirectory(defaultDirectory); - } - - //// Add - int returnVal = chooser.showDialog(PreferencesDialog.this, trans.get("pref.dlg.Add")); - if (returnVal == JFileChooser.APPROVE_OPTION) { - log.info(Markers.USER_MARKER, "Adding user thrust curve: " + chooser.getSelectedFile()); - defaultDirectory = chooser.getCurrentDirectory(); - String text = field.getText().trim(); - if (text.length() > 0) { - text += ";"; - } - text += chooser.getSelectedFile().getAbsolutePath(); - field.setText(text); - } - } - }); - panel.add(button, "gapright unrel"); - - //// Reset button - button = new JButton(trans.get("pref.dlg.but.reset")); - - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // First one sets to the default, but does not un-set the pref - field.setText(preferences.getDefaultUserThrustCurveFile().getAbsolutePath()); - preferences.setUserThrustCurveFiles(null); - } - }); - panel.add(button, "wrap"); - - //// Add directories, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external thrust curves. Changes will take effect the next time you start OpenRocket. - DescriptionArea desc = new DescriptionArea(trans.get("pref.dlg.DescriptionArea.Adddirectories"), 3, -3, false); - desc.setBackground(getBackground()); - panel.add(desc, "spanx, growx, wrap 40lp"); - - - - - //// Check for software updates at startup - final JCheckBox softwareUpdateBox = - new JCheckBox(trans.get("pref.dlg.checkbox.Checkupdates")); - softwareUpdateBox.setSelected(preferences.getCheckUpdates()); - softwareUpdateBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - preferences.setCheckUpdates(softwareUpdateBox.isSelected()); - } - }); - panel.add(softwareUpdateBox); - - //// Check now button - button = new JButton(trans.get("pref.dlg.but.checknow")); - //// Check for software updates now - button.setToolTipText(trans.get("pref.dlg.ttip.Checkupdatesnow")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - checkForUpdates(); - } - }); - panel.add(button, "right, wrap"); - - return panel; - } - - private JPanel simulationOptionsPane() { - JPanel panel = new JPanel(new MigLayout("fillx, ins 30lp n n n")); - - //// Confirm deletion of simulations: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Confirmdeletion"))); - panel.add(new JComboBox(new PrefBooleanSelector(Preferences.CONFIRM_DELETE_SIMULATION, - //// Delete - //// Confirm - trans.get("pref.dlg.PrefBooleanSelector1"), - trans.get("pref.dlg.PrefBooleanSelector2"), true)), "wrap, growx, sg combos"); - - - //// Automatically run all simulation out-dated by design changes. - final JCheckBox automaticallyRunSimsBox = - new JCheckBox(trans.get("pref.dlg.checkbox.Runsimulations")); - automaticallyRunSimsBox.setSelected(preferences.getAutoRunSimulations()); - automaticallyRunSimsBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - preferences.setAutoRunSimulations(automaticallyRunSimsBox.isSelected()); - } - }); - panel.add(automaticallyRunSimsBox, "wrap, growx, sg combos "); - - return panel; - } - - private JPanel unitsPane() { - JPanel panel = new JPanel(new MigLayout("", "[][]40lp[][]")); - JComboBox combo; - - //// Select your preferred units: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Selectprefunits")), "span, wrap paragraph"); - - - //// Rocket dimensions: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Rocketdimensions"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_LENGTH)); - panel.add(combo, "sizegroup boxes"); - - //// Line density: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Linedensity"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_LINE)); - panel.add(combo, "sizegroup boxes, wrap"); - - - //// Motor dimensions: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Motordimensions"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MOTOR_DIMENSIONS)); - panel.add(combo, "sizegroup boxes"); - - //// Surface density: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Surfacedensity"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_SURFACE)); - panel.add(combo, "sizegroup boxes, wrap"); - - - //// Distance: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Distance"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DISTANCE)); - panel.add(combo, "sizegroup boxes"); - - //// Bulk density:: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Bulkdensity"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_BULK)); - panel.add(combo, "sizegroup boxes, wrap"); - - - //// Velocity: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Velocity"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_VELOCITY)); - panel.add(combo, "sizegroup boxes"); - - //// Surface roughness: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Surfaceroughness"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROUGHNESS)); - panel.add(combo, "sizegroup boxes, wrap"); - - - //// Acceleration: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Acceleration"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ACCELERATION)); - panel.add(combo, "sizegroup boxes"); - - //// Area: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Area"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_AREA)); - panel.add(combo, "sizegroup boxes, wrap"); - - - //// Mass: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Mass"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MASS)); - panel.add(combo, "sizegroup boxes"); - - //// Angle: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Angle"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ANGLE)); - panel.add(combo, "sizegroup boxes, wrap"); - - - //// Force: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Force"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_FORCE)); - panel.add(combo, "sizegroup boxes"); - - //// Roll rate: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Rollrate"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROLL)); - panel.add(combo, "sizegroup boxes, wrap"); - - - //// Total impulse: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Totalimpulse"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_IMPULSE)); - panel.add(combo, "sizegroup boxes"); - - //// Temperature: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Temperature"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_TEMPERATURE)); - panel.add(combo, "sizegroup boxes, wrap"); - - //// Moment of inertia: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Momentofinertia"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_INERTIA)); - panel.add(combo, "sizegroup boxes"); - - //// Pressure: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Pressure"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_PRESSURE)); - panel.add(combo, "sizegroup boxes, wrap"); - - - //// Stability: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Stability"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_STABILITY)); - panel.add(combo, "sizegroup boxes"); - - //// Windspeed: - panel.add(new JLabel(trans.get("pref.dlg.lbl.Windspeed"))); - combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_WINDSPEED)); - panel.add(combo, "sizegroup boxes, wrap para"); - - - - - //// Default metric button - JButton button = new JButton(trans.get("pref.dlg.but.defaultmetric")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - UnitGroup.setDefaultMetricUnits(); - for (DefaultUnitSelector s : unitSelectors) - s.fireChange(); - } - }); - panel.add(button, "spanx, split 2, grow"); - - //// Default imperial button - button = new JButton(trans.get("pref.dlg.but.defaultimperial")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - UnitGroup.setDefaultImperialUnits(); - for (DefaultUnitSelector s : unitSelectors) - s.fireChange(); - } - }); - panel.add(button, "grow, wrap para"); - - //// The effects will take place the next time you open a window. - panel.add(new StyledLabel( - trans.get("pref.dlg.lbl.effect1"), -2, Style.ITALIC), - "spanx, wrap"); - - - return panel; - } - - - private JPanel graphicsOptionsPane() { - - JPanel panel = new JPanel(new MigLayout("fillx")); - - panel.add(new JPanel(new MigLayout("fill, ins n n n")) { - { //Editor Options - TitledBorder border = BorderFactory.createTitledBorder(trans.get("pref.dlg.lbl.DecalEditor")); - GUIUtil.changeFontStyle(border, Font.BOLD); - setBorder(border); - - ButtonGroup execGroup = new ButtonGroup(); - - JRadioButton showPrompt = new JRadioButton(trans.get("EditDecalDialog.lbl.prompt")); - showPrompt.setSelected(!preferences.isDecalEditorPreferenceSet()); - showPrompt.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (((JRadioButton) e.getItem()).isSelected()) { - preferences.clearDecalEditorPreference(); - } - } - }); - add(showPrompt, "wrap"); - execGroup.add(showPrompt); - - if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) { - - JRadioButton systemRadio = new JRadioButton(trans.get("EditDecalDialog.lbl.system")); - systemRadio.setSelected(preferences.isDecalEditorPreferenceSystem()); - systemRadio.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (((JRadioButton) e.getItem()).isSelected()) { - preferences.setDecalEditorPreference(true, null); - } - } - }); - add(systemRadio, "wrap"); - execGroup.add(systemRadio); - - } - - boolean commandLineIsSelected = preferences.isDecalEditorPreferenceSet() && !preferences.isDecalEditorPreferenceSystem(); - final JRadioButton commandRadio = new JRadioButton(trans.get("EditDecalDialog.lbl.cmdline")); - commandRadio.setSelected(commandLineIsSelected); - add(commandRadio, "wrap"); - execGroup.add(commandRadio); - - final JTextField commandText = new JTextField(); - commandText.setEnabled(commandLineIsSelected); - commandText.setText(commandLineIsSelected ? preferences.getDecalEditorCommandLine() : ""); - commandText.getDocument().addDocumentListener(new DocumentListener() { - - @Override - public void insertUpdate(DocumentEvent e) { - preferences.setDecalEditorPreference(false, commandText.getText()); - } - - @Override - public void removeUpdate(DocumentEvent e) { - preferences.setDecalEditorPreference(false, commandText.getText()); - } - - @Override - public void changedUpdate(DocumentEvent e) { - preferences.setDecalEditorPreference(false, commandText.getText()); - } - - }); - add(commandText, "growx, wrap"); - - final JButton chooser = new JButton(trans.get("EditDecalDialog.btn.chooser")); - chooser.setEnabled(commandLineIsSelected); - chooser.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser fc = new JFileChooser(); - int action = fc.showOpenDialog(SwingUtilities.windowForComponent(PreferencesDialog.this)); - if (action == JFileChooser.APPROVE_OPTION) { - String commandLine = fc.getSelectedFile().getAbsolutePath(); - commandText.setText(commandLine); - preferences.setDecalEditorPreference(false, commandLine); - } - - } - - }); - add(chooser, "wrap"); - - - commandRadio.addChangeListener(new ChangeListener() { - - @Override - public void stateChanged(ChangeEvent e) { - boolean enabled = commandRadio.isSelected(); - commandText.setEnabled(enabled); - chooser.setEnabled(enabled); - } - - }); - } - }, "growx, span"); - - panel.add(new JPanel(new MigLayout("fill, ins n n n")) { - {/////GL Options - TitledBorder border = BorderFactory.createTitledBorder(trans.get("pref.dlg.opengl.lbl.title")); - GUIUtil.changeFontStyle(border, Font.BOLD); - setBorder(border); - - //// The effects will take place the next time you open a window. - add(new StyledLabel( - trans.get("pref.dlg.lbl.effect1"), -2, Style.ITALIC), - "spanx, wrap"); - - BooleanModel enableGLModel = new BooleanModel(preferences.getBoolean(Preferences.OPENGL_ENABLED, true)); - final JCheckBox enableGL = new JCheckBox(enableGLModel); - enableGL.setText(trans.get("pref.dlg.opengl.but.enableGL")); - enableGL.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - preferences.putBoolean(Preferences.OPENGL_ENABLED, enableGL.isSelected()); - } - }); - add(enableGL, "wrap"); - - final JCheckBox enableAA = new JCheckBox(trans.get("pref.dlg.opengl.but.enableAA")); - enableAA.setSelected(preferences.getBoolean(Preferences.OPENGL_ENABLE_AA, true)); - enableAA.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - preferences.putBoolean(Preferences.OPENGL_ENABLE_AA, enableAA.isSelected()); - } - }); - enableGLModel.addEnableComponent(enableAA); - add(enableAA, "wrap"); - - final JCheckBox useFBO = new JCheckBox(trans.get("pref.dlg.opengl.lbl.useFBO")); - useFBO.setSelected(preferences.getBoolean(Preferences.OPENGL_USE_FBO, false)); - useFBO.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - preferences.putBoolean(Preferences.OPENGL_USE_FBO, useFBO.isSelected()); - } - }); - enableGLModel.addEnableComponent(useFBO); - add(useFBO, "wrap"); - } - }, "growx, span"); - return panel; - } - - - - private class DefaultUnitSelector extends AbstractListModel implements ComboBoxModel { - - private final UnitGroup group; - - public DefaultUnitSelector(UnitGroup group) { - this.group = group; - unitSelectors.add(this); - } - - @Override - public Object getSelectedItem() { - return group.getDefaultUnit(); - } - - @Override - public void setSelectedItem(Object item) { - if (item == null) { - // Clear selection - huh? - return; - } - if (!(item instanceof Unit)) { - throw new IllegalArgumentException("Illegal argument " + item); - } - group.setDefaultUnit(group.getUnitIndex((Unit) item)); - } - - @Override - public Object getElementAt(int index) { - return group.getUnit(index); - } - - @Override - public int getSize() { - return group.getUnitCount(); - } - - - public void fireChange() { - this.fireContentsChanged(this, 0, this.getSize()); - } - } - - - - private class PrefChoiceSelector extends AbstractListModel implements ComboBoxModel { - private final String preference; - private final String[] descriptions; - - public PrefChoiceSelector(String preference, String... descriptions) { - this.preference = preference; - this.descriptions = descriptions; - } - - @Override - public Object getSelectedItem() { - return descriptions[preferences.getChoice(preference, descriptions.length, 0)]; - } - - @Override - public void setSelectedItem(Object item) { - if (item == null) { - // Clear selection - huh? - return; - } - if (!(item instanceof String)) { - throw new IllegalArgumentException("Illegal argument " + item); - } - int index; - for (index = 0; index < descriptions.length; index++) { - if (((String) item).equalsIgnoreCase(descriptions[index])) - break; - } - if (index >= descriptions.length) { - throw new IllegalArgumentException("Illegal argument " + item); - } - - preferences.putChoice(preference, index); - } - - @Override - public Object getElementAt(int index) { - return descriptions[index]; - } - - @Override - public int getSize() { - return descriptions.length; - } - } - - - private class PrefBooleanSelector extends AbstractListModel implements ComboBoxModel { - private final String preference; - private final String trueDesc, falseDesc; - private final boolean def; - - public PrefBooleanSelector(String preference, String falseDescription, - String trueDescription, boolean defaultState) { - this.preference = preference; - this.trueDesc = trueDescription; - this.falseDesc = falseDescription; - this.def = defaultState; - } - - @Override - public Object getSelectedItem() { - if (preferences.getBoolean(preference, def)) { - return trueDesc; - } else { - return falseDesc; - } - } - - @Override - public void setSelectedItem(Object item) { - if (item == null) { - // Clear selection - huh? - return; - } - if (!(item instanceof String)) { - throw new IllegalArgumentException("Illegal argument " + item); - } - - if (trueDesc.equals(item)) { - preferences.putBoolean(preference, true); - } else if (falseDesc.equals(item)) { - preferences.putBoolean(preference, false); - } else { - throw new IllegalArgumentException("Illegal argument " + item); - } - } - - @Override - public Object getElementAt(int index) { - switch (index) { - case 0: - return def ? trueDesc : falseDesc; - - case 1: - return def ? falseDesc : trueDesc; - - default: - throw new IndexOutOfBoundsException("Boolean asked for index=" + index); - } - } - - @Override - public int getSize() { - return 2; - } - } - - - private void checkForUpdates() { - final UpdateInfoRetriever retriever = new UpdateInfoRetriever(); - retriever.start(); - - - // Progress dialog - final JDialog dialog1 = new JDialog(this, ModalityType.APPLICATION_MODAL); - JPanel panel = new JPanel(new MigLayout()); - - //// Checking for updates... - panel.add(new JLabel(trans.get("pref.dlg.lbl.Checkingupdates")), "wrap"); - - JProgressBar bar = new JProgressBar(); - bar.setIndeterminate(true); - panel.add(bar, "growx, wrap para"); - - //// Cancel button - JButton cancel = new JButton(trans.get("dlg.but.cancel")); - cancel.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - dialog1.dispose(); - } - }); - panel.add(cancel, "right"); - dialog1.add(panel); - - GUIUtil.setDisposableDialogOptions(dialog1, cancel); - - - // Timer to monitor progress - final Timer timer = new Timer(100, null); - final long startTime = System.currentTimeMillis(); - - ActionListener listener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (!retriever.isRunning() || startTime + 10000 < System.currentTimeMillis()) { - timer.stop(); - dialog1.dispose(); - } - } - }; - timer.addActionListener(listener); - timer.start(); - - - // Wait for action - dialog1.setVisible(true); - - - // Check result - UpdateInfo info = retriever.getUpdateInfo(); - if (info == null) { - JOptionPane.showMessageDialog(this, - //// An error occurred while communicating with the server. - trans.get("pref.dlg.lbl.msg1"), - //// Unable to retrieve update information - trans.get("pref.dlg.lbl.msg2"), JOptionPane.WARNING_MESSAGE, null); - } else if (info.getLatestVersion() == null || - info.getLatestVersion().equals("") || - BuildProperties.getVersion().equalsIgnoreCase(info.getLatestVersion())) { - JOptionPane.showMessageDialog(this, - //// You are running the latest version of OpenRocket. - trans.get("pref.dlg.lbl.msg3"), - //// No updates available - trans.get("pref.dlg.lbl.msg4"), JOptionPane.INFORMATION_MESSAGE, null); - } else { - UpdateInfoDialog infoDialog = new UpdateInfoDialog(info); - infoDialog.setVisible(true); - if (infoDialog.isReminderSelected()) { - preferences.putString(SwingPreferences.LAST_UPDATE, ""); - } else { - preferences.putString(SwingPreferences.LAST_UPDATE, info.getLatestVersion()); - } - } - - } - - - //////// Singleton implementation //////// - private static PreferencesDialog dialog = null; - + public static void showPreferences(Window parent) { if (dialog != null) { dialog.dispose(); @@ -961,6 +108,5 @@ public class PreferencesDialog extends JDialog { dialog = new PreferencesDialog(parent); dialog.setVisible(true); } - - + } diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesPanel.java new file mode 100644 index 000000000..4b92bcd1e --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesPanel.java @@ -0,0 +1,193 @@ +package net.sf.openrocket.gui.dialogs.preferences; + +import java.awt.LayoutManager; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.AbstractListModel; +import javax.swing.ComboBoxModel; +import javax.swing.JDialog; +import javax.swing.JPanel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.Unit; +import net.sf.openrocket.unit.UnitGroup; + +public abstract class PreferencesPanel extends JPanel { + protected static final Logger log = LoggerFactory.getLogger(PreferencesDialog.class); + + protected final List unitSelectors = new ArrayList(); + + protected File defaultDirectory = null; + protected static final Translator trans = Application.getTranslator(); + + protected final SwingPreferences preferences = (SwingPreferences) Application.getPreferences(); + + protected JDialog parentDialog; + protected PreferencesPanel(JDialog parent, LayoutManager layout) { + super(layout); + this.parentDialog=parent; + } + + protected PreferencesPanel(LayoutManager layout) { + super(layout); + } + + protected class DefaultUnitSelector extends AbstractListModel implements ComboBoxModel { + + private final UnitGroup group; + + public DefaultUnitSelector(UnitGroup group) { + this.group = group; + unitSelectors.add(this); + } + + @Override + public Object getSelectedItem() { + return group.getDefaultUnit(); + } + + @Override + public void setSelectedItem(Object item) { + if (item == null) { + // Clear selection - huh? + return; + } + if (!(item instanceof Unit)) { + throw new IllegalArgumentException("Illegal argument " + item); + } + group.setDefaultUnit(group.getUnitIndex((Unit) item)); + } + + @Override + public Object getElementAt(int index) { + return group.getUnit(index); + } + + @Override + public int getSize() { + return group.getUnitCount(); + } + + + public void fireChange() { + this.fireContentsChanged(this, 0, this.getSize()); + } + } + + + + protected class PrefChoiceSelector extends AbstractListModel implements ComboBoxModel { + private final String preference; + private final String[] descriptions; + + public PrefChoiceSelector(String preference, String... descriptions) { + this.preference = preference; + this.descriptions = descriptions; + } + + @Override + public Object getSelectedItem() { + return descriptions[preferences.getChoice(preference, descriptions.length, 0)]; + } + + @Override + public void setSelectedItem(Object item) { + if (item == null) { + // Clear selection - huh? + return; + } + if (!(item instanceof String)) { + throw new IllegalArgumentException("Illegal argument " + item); + } + int index; + for (index = 0; index < descriptions.length; index++) { + if (((String) item).equalsIgnoreCase(descriptions[index])) + break; + } + if (index >= descriptions.length) { + throw new IllegalArgumentException("Illegal argument " + item); + } + + preferences.putChoice(preference, index); + } + + @Override + public Object getElementAt(int index) { + return descriptions[index]; + } + + @Override + public int getSize() { + return descriptions.length; + } + } + + + protected class PrefBooleanSelector extends AbstractListModel implements ComboBoxModel { + private final String preference; + private final String trueDesc, falseDesc; + private final boolean def; + + public PrefBooleanSelector(String preference, String falseDescription, + String trueDescription, boolean defaultState) { + this.preference = preference; + this.trueDesc = trueDescription; + this.falseDesc = falseDescription; + this.def = defaultState; + } + + @Override + public Object getSelectedItem() { + if (preferences.getBoolean(preference, def)) { + return trueDesc; + } else { + return falseDesc; + } + } + + @Override + public void setSelectedItem(Object item) { + if (item == null) { + // Clear selection - huh? + return; + } + if (!(item instanceof String)) { + throw new IllegalArgumentException("Illegal argument " + item); + } + + if (trueDesc.equals(item)) { + preferences.putBoolean(preference, true); + } else if (falseDesc.equals(item)) { + preferences.putBoolean(preference, false); + } else { + throw new IllegalArgumentException("Illegal argument " + item); + } + } + + @Override + public Object getElementAt(int index) { + switch (index) { + case 0: + return def ? trueDesc : falseDesc; + + case 1: + return def ? falseDesc : trueDesc; + + default: + throw new IndexOutOfBoundsException("Boolean asked for index=" + index); + } + } + + @Override + public int getSize() { + return 2; + } + } +} diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/SimulationPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/SimulationPreferencesPanel.java new file mode 100644 index 000000000..9cfd23d07 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/SimulationPreferencesPanel.java @@ -0,0 +1,85 @@ +package net.sf.openrocket.gui.dialogs.preferences; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JCheckBox; + +import net.miginfocom.swing.MigLayout; + +public class SimulationPreferencesPanel extends PreferencesPanel { + + /* + * private double launchRodLength = 1; + * + * private boolean launchIntoWind = true; private double launchRodAngle = 0; + * + * private double windDirection = Math.PI / 2; private double + * launchRodDirection = 0; + * + * + * private double windAverage = 2.0; private double windTurbulence = 0.1; + * + * private double launchAltitude = 0; private double launchLatitude = 45; + * private double launchLongitude = 0; private GeodeticComputationStrategy + * geodeticComputation = GeodeticComputationStrategy.SPHERICAL; + */ + + public SimulationPreferencesPanel() { + super(new MigLayout("fillx, ins 30lp n n n")); + + // Confirm deletion of simulations: + final JCheckBox confirmDelete = new JCheckBox( + trans.get("pref.dlg.lbl.Confirmdeletion")); + confirmDelete.setSelected(preferences.getConfirmSimDeletion()); + confirmDelete.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.setAutoRunSimulations(confirmDelete.isSelected()); + } + }); + this.add(confirmDelete, "wrap, growx, sg combos "); + + // Automatically run all simulation out-dated by design changes. + final JCheckBox automaticallyRunSimsBox = new JCheckBox( + trans.get("pref.dlg.checkbox.Runsimulations")); + automaticallyRunSimsBox + .setSelected(preferences.getAutoRunSimulations()); + automaticallyRunSimsBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.setAutoRunSimulations(automaticallyRunSimsBox + .isSelected()); + } + }); + this.add(automaticallyRunSimsBox, "wrap, growx, sg combos "); + + // private double launchRodLength = 1; + + // Keep launch rod aligned with the wind + final JCheckBox launchIntoWind = new JCheckBox( + trans.get("simedtdlg.checkbox.Intowind")); + launchIntoWind.setSelected(preferences.getLaunchIntoWind()); + launchIntoWind.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + preferences.setLaunchIntoWind(launchIntoWind.isSelected()); + } + }); + this.add(launchIntoWind, "wrap, growx, sg combos "); + + // private double launchRodAngle = 0; + // launchRodDirection = 0; + + // private double windDirection = Math.PI / 2; private double + // private double windAverage = 2.0; + // private double windTurbulence = 0.1; + + // private double launchAltitude = 0; + // private double launchLatitude = 45; + // private double launchLongitude = 0; + // private GeodeticComputationStrategy + // geodeticComputation = GeodeticComputationStrategy.SPHERICAL; + + } +} diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preferences/UnitsPreferencesPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/UnitsPreferencesPanel.java new file mode 100644 index 000000000..963197ec2 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/preferences/UnitsPreferencesPanel.java @@ -0,0 +1,174 @@ +package net.sf.openrocket.gui.dialogs.preferences; + +import java.awt.LayoutManager; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JLabel; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.gui.components.StyledLabel; +import net.sf.openrocket.gui.components.StyledLabel.Style; +import net.sf.openrocket.unit.UnitGroup; + +public class UnitsPreferencesPanel extends PreferencesPanel { + + public UnitsPreferencesPanel(JDialog parent) { + super(parent, new MigLayout("", "[][]40lp[][]")); + JComboBox combo; + + //// Select your preferred units: + this.add(new JLabel(trans.get("pref.dlg.lbl.Selectprefunits")), "span, wrap paragraph"); + + + //// Rocket dimensions: + this.add(new JLabel(trans.get("pref.dlg.lbl.Rocketdimensions"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_LENGTH)); + this.add(combo, "sizegroup boxes"); + + //// Line density: + this.add(new JLabel(trans.get("pref.dlg.lbl.Linedensity"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_LINE)); + this.add(combo, "sizegroup boxes, wrap"); + + + //// Motor dimensions: + this.add(new JLabel(trans.get("pref.dlg.lbl.Motordimensions"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MOTOR_DIMENSIONS)); + this.add(combo, "sizegroup boxes"); + + //// Surface density: + this.add(new JLabel(trans.get("pref.dlg.lbl.Surfacedensity"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_SURFACE)); + this.add(combo, "sizegroup boxes, wrap"); + + + //// Distance: + this.add(new JLabel(trans.get("pref.dlg.lbl.Distance"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DISTANCE)); + this.add(combo, "sizegroup boxes"); + + //// Bulk density:: + this.add(new JLabel(trans.get("pref.dlg.lbl.Bulkdensity"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_BULK)); + this.add(combo, "sizegroup boxes, wrap"); + + + //// Velocity: + this.add(new JLabel(trans.get("pref.dlg.lbl.Velocity"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_VELOCITY)); + this.add(combo, "sizegroup boxes"); + + //// Surface roughness: + this.add(new JLabel(trans.get("pref.dlg.lbl.Surfaceroughness"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROUGHNESS)); + this.add(combo, "sizegroup boxes, wrap"); + + + //// Acceleration: + this.add(new JLabel(trans.get("pref.dlg.lbl.Acceleration"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ACCELERATION)); + this.add(combo, "sizegroup boxes"); + + //// Area: + this.add(new JLabel(trans.get("pref.dlg.lbl.Area"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_AREA)); + this.add(combo, "sizegroup boxes, wrap"); + + + //// Mass: + this.add(new JLabel(trans.get("pref.dlg.lbl.Mass"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MASS)); + this.add(combo, "sizegroup boxes"); + + //// Angle: + this.add(new JLabel(trans.get("pref.dlg.lbl.Angle"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ANGLE)); + this.add(combo, "sizegroup boxes, wrap"); + + + //// Force: + this.add(new JLabel(trans.get("pref.dlg.lbl.Force"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_FORCE)); + this.add(combo, "sizegroup boxes"); + + //// Roll rate: + this.add(new JLabel(trans.get("pref.dlg.lbl.Rollrate"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROLL)); + this.add(combo, "sizegroup boxes, wrap"); + + + //// Total impulse: + this.add(new JLabel(trans.get("pref.dlg.lbl.Totalimpulse"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_IMPULSE)); + this.add(combo, "sizegroup boxes"); + + //// Temperature: + this.add(new JLabel(trans.get("pref.dlg.lbl.Temperature"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_TEMPERATURE)); + this.add(combo, "sizegroup boxes, wrap"); + + //// Moment of inertia: + this.add(new JLabel(trans.get("pref.dlg.lbl.Momentofinertia"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_INERTIA)); + this.add(combo, "sizegroup boxes"); + + //// Pressure: + this.add(new JLabel(trans.get("pref.dlg.lbl.Pressure"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_PRESSURE)); + this.add(combo, "sizegroup boxes, wrap"); + + + //// Stability: + this.add(new JLabel(trans.get("pref.dlg.lbl.Stability"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_STABILITY)); + this.add(combo, "sizegroup boxes"); + + //// Windspeed: + this.add(new JLabel(trans.get("pref.dlg.lbl.Windspeed"))); + combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_WINDSPEED)); + this.add(combo, "sizegroup boxes, wrap para"); + + + + + //// Default metric button + JButton button = new JButton(trans.get("pref.dlg.but.defaultmetric")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + UnitGroup.setDefaultMetricUnits(); + for (DefaultUnitSelector s : unitSelectors) + s.fireChange(); + } + }); + this.add(button, "spanx, split 2, grow"); + + //// Default imperial button + button = new JButton(trans.get("pref.dlg.but.defaultimperial")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + UnitGroup.setDefaultImperialUnits(); + for (DefaultUnitSelector s : unitSelectors) + s.fireChange(); + } + }); + this.add(button, "grow, wrap para"); + + //// The effects will take place the next time you open a window. + this.add(new StyledLabel( + trans.get("pref.dlg.lbl.effect1"), -2, Style.ITALIC), + "spanx, wrap"); + + } + + public UnitsPreferencesPanel(LayoutManager layout) { + super(layout); + // TODO Auto-generated constructor stub + } + +}