diff --git a/swing/src/main/java/info/openrocket/swing/gui/adaptors/DoubleModel.java b/swing/src/main/java/info/openrocket/swing/gui/adaptors/DoubleModel.java index a557e1420..4d64389e6 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/adaptors/DoubleModel.java +++ b/swing/src/main/java/info/openrocket/swing/gui/adaptors/DoubleModel.java @@ -618,7 +618,9 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat private Unit currentUnit; private final double minValue; - private double maxValue; + private final double maxValue; + private DoubleModel minModel; + private DoubleModel maxModel; private String toString = null; @@ -697,7 +699,7 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat * @param max Maximum value allowed (in SI units) */ public DoubleModel(Object source, String valueName, double multiplier, UnitGroup unit, - double min, double max) { + Object min, Object max) { this.modelInvalidator = new ModelInvalidator(source, this); this.source = source; this.valueName = valueName; @@ -705,11 +707,28 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat this.units = unit; currentUnit = units.getDefaultUnit(); + + if (min instanceof DoubleModel) { + this.minModel = (DoubleModel) min; + this.minValue = this.minModel.getValue(); + this.minModel.addChangeListener(this); + } else if (min instanceof Double) { + this.minValue = (Double) min; + } else { + this.minValue = Double.NEGATIVE_INFINITY; + } + + if (max instanceof DoubleModel) { + this.maxModel = (DoubleModel) max; + this.maxValue = this.maxModel.getValue(); + this.maxModel.addChangeListener(this); + } else if (max instanceof Double) { + this.maxValue = (Double) max; + } else { + this.maxValue = Double.POSITIVE_INFINITY; + } - this.minValue = min; - this.maxValue = max; - - if(RocketComponent.class.isAssignableFrom(source.getClass())) { + if (RocketComponent.class.isAssignableFrom(source.getClass())) { ((RocketComponent)source).addChangeListener(this); } @@ -751,6 +770,11 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat double min) { this(source, valueName, multiplier, unit, min, Double.POSITIVE_INFINITY); } + + public DoubleModel(Object source, String valueName, double multiplier, UnitGroup unit, + DoubleModel min) { + this(source, valueName, multiplier, unit, min, Double.POSITIVE_INFINITY); + } public DoubleModel(Object source, String valueName, double multiplier, UnitGroup unit) { this(source, valueName, multiplier, unit, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); @@ -764,6 +788,22 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat public DoubleModel(Object source, String valueName, UnitGroup unit, double min) { this(source, valueName, 1.0, unit, min, Double.POSITIVE_INFINITY); } + + public DoubleModel(Object source, String valueName, UnitGroup unit, DoubleModel min) { + this(source, valueName, 1.0, unit, min, Double.POSITIVE_INFINITY); + } + + public DoubleModel(Object source, String valueName, UnitGroup unit, double min, DoubleModel max) { + this(source, valueName, 1.0, unit, min, max); + } + + public DoubleModel(Object source, String valueName, UnitGroup unit, DoubleModel min, double max) { + this(source, valueName, 1.0, unit, min, max); + } + + public DoubleModel(Object source, String valueName, UnitGroup unit, DoubleModel min, DoubleModel max) { + this(source, valueName, 1.0, unit, min, max); + } public DoubleModel(Object source, String valueName, UnitGroup unit) { this(source, valueName, 1.0, unit, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); @@ -777,10 +817,26 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat public DoubleModel(Object source, String valueName, double min) { this(source, valueName, 1.0, UnitGroup.UNITS_NONE, min, Double.POSITIVE_INFINITY); } + + public DoubleModel(Object source, String valueName, DoubleModel min) { + this(source, valueName, 1.0, UnitGroup.UNITS_NONE, min, Double.POSITIVE_INFINITY); + } public DoubleModel(Object source, String valueName, double min, double max) { this(source, valueName, 1.0, UnitGroup.UNITS_NONE, min, max); } + + public DoubleModel(Object source, String valueName, DoubleModel min, double max) { + this(source, valueName, 1.0, UnitGroup.UNITS_NONE, min, max); + } + + public DoubleModel(Object source, String valueName, double min, DoubleModel max) { + this(source, valueName, 1.0, UnitGroup.UNITS_NONE, min, max); + } + + public DoubleModel(Object source, String valueName, DoubleModel min, DoubleModel max) { + this(source, valueName, 1.0, UnitGroup.UNITS_NONE, min, max); + } /** @@ -806,7 +862,9 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat public void setValue(double v) { modelInvalidator.checkState(true); - double clampedValue = MathUtil.clamp(v, minValue, maxValue); + double minVal = (minModel != null) ? minModel.getValue() : minValue; + double maxVal = (maxModel != null) ? maxModel.getValue() : maxValue; + double clampedValue = MathUtil.clamp(v, minVal, maxVal); if (clampedValue != v) { log.debug("Clamped value " + v + " to " + clampedValue + " for " + this); v = clampedValue; @@ -833,7 +891,15 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat throw Reflection.handleWrappedException(e); } } - + + public void setMinModel(DoubleModel minModel) { + this.minModel = minModel; + } + + public void setMaxModel(DoubleModel maxModel) { + this.maxModel = maxModel; + } + /** * Returns whether setting the value automatically is available. */ @@ -983,6 +1049,8 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat @Override public void invalidateMe() { modelInvalidator.invalidateMe(); + if (minModel != null) minModel.removeChangeListener(this); + if (maxModel != null) maxModel.removeChangeListener(this); } @@ -1022,6 +1090,13 @@ public class DoubleModel implements StateChangeListener, ChangeSource, Invalidat @Override public void stateChanged(EventObject e) { modelInvalidator.checkState(true); + + if (e.getSource() == minModel || e.getSource() == maxModel) { + // Min or max value has changed, we need to ensure our current value is still within bounds + double currentValue = getValue(); + setValue(currentValue); // This will clamp the value if necessary + return; + } double v = getValue(); boolean b = isAutomatic();