Merge pull request #998 from SiboVG/issue-871

[fixes #871] Automatic base/outer diameter unexpected results/warnings
This commit is contained in:
Joe Pfeiffer 2021-10-05 19:05:39 -06:00 committed by GitHub
commit c8f985ea32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 264 additions and 47 deletions

View File

@ -769,6 +769,9 @@ BodyTubecfg.tab.Generalproperties = General properties
BodyTubecfg.tab.Motor = Motor BodyTubecfg.tab.Motor = Motor
BodyTubecfg.tab.Motormountconf = Motor mount configuration BodyTubecfg.tab.Motormountconf = Motor mount configuration
BodyTubecfg.checkbox.Automatic = Automatic BodyTubecfg.checkbox.Automatic = Automatic
BodyTubecfg.checkbox.ttip.Automatic = Use the diameter of the previous/next component
BodyTubecfg.checkbox.ttip.Automatic_noReferenceComponent = There is no previous/next component to take the diameter of
BodyTubecfg.checkbox.ttip.Automatic_alreadyAuto = The previous/next component already has its auto setting turned on
BodyTubecfg.checkbox.Filled = Filled BodyTubecfg.checkbox.Filled = Filled
! FinSetConfig ! FinSetConfig
@ -1039,6 +1042,9 @@ NoseConeCfg.lbl.Shapeparam = Shape parameter:
NoseConeCfg.lbl.Noseconelength = Nose cone length: NoseConeCfg.lbl.Noseconelength = Nose cone length:
NoseConeCfg.lbl.Basediam = Base diameter: NoseConeCfg.lbl.Basediam = Base diameter:
NoseConeCfg.checkbox.Automatic = Automatic NoseConeCfg.checkbox.Automatic = Automatic
NoseConeCfg.checkbox.ttip.Automatic = Use the diameter of the next component
NoseConeCfg.checkbox.ttip.Automatic_noReferenceComponent = There is no next component to take the diameter of
NoseConeCfg.checkbox.ttip.Automatic_alreadyAuto = The next component already has its auto setting turned on
NoseConeCfg.lbl.Wallthickness = Wall thickness: NoseConeCfg.lbl.Wallthickness = Wall thickness:
NoseConeCfg.checkbox.Filled = Filled NoseConeCfg.checkbox.Filled = Filled
NoseConeCfg.tab.General = General NoseConeCfg.tab.General = General
@ -1140,6 +1146,9 @@ TransitionCfg.lbl.Shapeparam = Shape parameter:
TransitionCfg.lbl.Transitionlength = Transition length: TransitionCfg.lbl.Transitionlength = Transition length:
TransitionCfg.lbl.Forediam = Fore diameter: TransitionCfg.lbl.Forediam = Fore diameter:
TransitionCfg.checkbox.Automatic = Automatic TransitionCfg.checkbox.Automatic = Automatic
TransitionCfg.checkbox.ttip.Automatic = Use the diameter of the previous/next component
TransitionCfg.checkbox.ttip.Automatic_noReferenceComponent = There is no previous/next component to take the diameter of
TransitionCfg.checkbox.ttip.Automatic_alreadyAuto = The previous/next component already has its auto setting turned on
TransitionCfg.lbl.Aftdiam = Aft diameter: TransitionCfg.lbl.Aftdiam = Aft diameter:
TransitionCfg.lbl.Wallthickness = Wall thickness: TransitionCfg.lbl.Wallthickness = Wall thickness:
TransitionCfg.checkbox.Filled = Filled TransitionCfg.checkbox.Filled = Filled

View File

@ -152,7 +152,7 @@ class DocumentConfig {
// BodyTube // BodyTube
setters.put("BodyTube:radius", new DoubleSetter( setters.put("BodyTube:radius", new DoubleSetter(
Reflection.findMethod(BodyTube.class, "setOuterRadius", double.class), Reflection.findMethod(BodyTube.class, "setOuterRadius", double.class),
"auto", "auto", " ",
Reflection.findMethod(BodyTube.class, "setOuterRadiusAutomatic", boolean.class))); Reflection.findMethod(BodyTube.class, "setOuterRadiusAutomatic", boolean.class)));
// Parallel Stage // Parallel Stage
@ -204,11 +204,11 @@ class DocumentConfig {
setters.put("Transition:foreradius", new DoubleSetter( setters.put("Transition:foreradius", new DoubleSetter(
Reflection.findMethod(Transition.class, "setForeRadius", double.class), Reflection.findMethod(Transition.class, "setForeRadius", double.class),
"auto", "auto", " ",
Reflection.findMethod(Transition.class, "setForeRadiusAutomatic", boolean.class))); Reflection.findMethod(Transition.class, "setForeRadiusAutomatic", boolean.class)));
setters.put("Transition:aftradius", new DoubleSetter( setters.put("Transition:aftradius", new DoubleSetter(
Reflection.findMethod(Transition.class, "setAftRadius", double.class), Reflection.findMethod(Transition.class, "setAftRadius", double.class),
"auto", "auto", " ",
Reflection.findMethod(Transition.class, "setAftRadiusAutomatic", boolean.class))); Reflection.findMethod(Transition.class, "setAftRadiusAutomatic", boolean.class)));
setters.put("Transition:foreshoulderradius", new DoubleSetter( setters.put("Transition:foreshoulderradius", new DoubleSetter(

View File

@ -1,6 +1,8 @@
package net.sf.openrocket.file.openrocket.importt; package net.sf.openrocket.file.openrocket.importt;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects;
import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.aerodynamics.WarningSet;
@ -17,6 +19,7 @@ class DoubleSetter implements Setter {
private final String specialString; private final String specialString;
private final Reflection.Method specialMethod; private final Reflection.Method specialMethod;
private final double multiplier; private final double multiplier;
private String separator;
/** /**
* Set only the double value. * Set only the double value.
@ -59,6 +62,23 @@ class DoubleSetter implements Setter {
this.specialMethod = specialMethod; this.specialMethod = specialMethod;
this.multiplier = 1.0; this.multiplier = 1.0;
} }
/**
* Set the double value, or if the value equals the special string, use the
* special setter and set it to true. If the input string contains more information
* besides the special string, you can specify which separator should be used for
* this extra information. The part before the separator is then the special string
* and the part after the separator is the set value.
*
* @param set double setter.
* @param special special string
* @param specialMethod boolean setter.
*/
public DoubleSetter(Reflection.Method set, String special, String separator,
Reflection.Method specialMethod) {
this(set, special, specialMethod);
this.separator = separator;
}
/** /**
@ -80,26 +100,39 @@ class DoubleSetter implements Setter {
WarningSet warnings) { WarningSet warnings) {
s = s.trim(); s = s.trim();
String special = s;
// Check for special case String data = s;
if (specialMethod != null && s.equalsIgnoreCase(specialString)) { String[] args = null;
specialMethod.invoke(c, true);
return; // Extract special string and data if s contains multiple data elements, separated by separator
if (separator != null) {
args = s.split(this.separator);
if (args.length > 1) {
special = args[0];
data = String.join(separator, Arrays.copyOfRange(args, 1, args.length));
}
} }
// Normal case // Normal case
try { if (!special.equalsIgnoreCase(specialString) || (args != null && args.length > 1)) {
double d = Double.parseDouble(s); try {
double d = Double.parseDouble(data);
if (configGetter == null) {
setMethod.invoke(c, d * multiplier); if (configGetter == null) {
} else { setMethod.invoke(c, d * multiplier);
FlightConfigurableParameterSet<?> config = (FlightConfigurableParameterSet<?>) configGetter.invoke(c); } else {
Object obj = config.getDefault(); FlightConfigurableParameterSet<?> config = (FlightConfigurableParameterSet<?>) configGetter.invoke(c);
setMethod.invoke(obj, d * multiplier); Object obj = config.getDefault();
setMethod.invoke(obj, d * multiplier);
}
} catch (NumberFormatException e) {
warnings.add(Warning.FILE_INVALID_PARAMETER + " data: '" + data + "' - " + c.getName());
} }
} catch (NumberFormatException e) { }
warnings.add(Warning.FILE_INVALID_PARAMETER);
// Check for special case
if (specialMethod != null && special.equalsIgnoreCase(specialString)) {
specialMethod.invoke(c, true);
} }
} }
} }

View File

@ -22,8 +22,9 @@ public class BodyTubeSaver extends SymmetricComponentSaver {
super.addParams(c, elements); super.addParams(c, elements);
net.sf.openrocket.rocketcomponent.BodyTube tube = (net.sf.openrocket.rocketcomponent.BodyTube) c; net.sf.openrocket.rocketcomponent.BodyTube tube = (net.sf.openrocket.rocketcomponent.BodyTube) c;
if (tube.isOuterRadiusAutomatic()) if (tube.isOuterRadiusAutomatic()) {
elements.add("<radius>auto</radius>"); elements.add("<radius>auto " + tube.getOuterRadiusNoAutomatic() + "</radius>");
}
else else
elements.add("<radius>" + tube.getOuterRadius() + "</radius>"); elements.add("<radius>" + tube.getOuterRadius() + "</radius>");

View File

@ -45,13 +45,13 @@ public class TransitionSaver extends SymmetricComponentSaver {
if (!nosecone) { if (!nosecone) {
if (trans.isForeRadiusAutomatic()) if (trans.isForeRadiusAutomatic())
elements.add("<foreradius>auto</foreradius>"); elements.add("<foreradius>auto " + trans.getForeRadiusNoAutomatic() + "</foreradius>");
else else
elements.add("<foreradius>" + trans.getForeRadius() + "</foreradius>"); elements.add("<foreradius>" + trans.getForeRadius() + "</foreradius>");
} }
if (trans.isAftRadiusAutomatic()) if (trans.isAftRadiusAutomatic())
elements.add("<aftradius>auto</aftradius>"); elements.add("<aftradius>auto " + trans.getAftRadiusNoAutomatic() + "</aftradius>");
else else
elements.add("<aftradius>" + trans.getAftRadius() + "</aftradius>"); elements.add("<aftradius>" + trans.getAftRadius() + "</aftradius>");

View File

@ -1,10 +1,7 @@
package net.sf.openrocket.rocketcomponent; package net.sf.openrocket.rocketcomponent;
import java.util.EventObject;
import java.util.Iterator; import java.util.Iterator;
import net.sf.openrocket.appearance.Appearance;
import net.sf.openrocket.appearance.Decal;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.motor.MotorConfiguration;
@ -25,6 +22,8 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
private double outerRadius = 0; private double outerRadius = 0;
private boolean autoRadius = false; // Radius chosen automatically based on parent component private boolean autoRadius = false; // Radius chosen automatically based on parent component
private SymmetricComponent refComp = null; // Reference component that is used for the autoRadius
// When changing the inner radius, thickness is modified // When changing the inner radius, thickness is modified
private double overhang = 0; private double overhang = 0;
@ -79,13 +78,17 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
// Return auto radius from front or rear // Return auto radius from front or rear
double r = -1; double r = -1;
SymmetricComponent c = this.getPreviousSymmetricComponent(); SymmetricComponent c = this.getPreviousSymmetricComponent();
if (c != null) { // Don't use the radius of a component who already has its auto diameter enabled
if (c != null && !c.usesNextCompAutomatic()) {
r = c.getFrontAutoRadius(); r = c.getFrontAutoRadius();
refComp = c;
} }
if (r < 0) { if (r < 0) {
c = this.getNextSymmetricComponent(); c = this.getNextSymmetricComponent();
if (c != null) { // Don't use the radius of a component who already has its auto diameter enabled
if (c != null && !c.usesPreviousCompAutomatic()) {
r = c.getRearAutoRadius(); r = c.getRearAutoRadius();
refComp = c;
} }
} }
if (r < 0) if (r < 0)
@ -94,6 +97,14 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
} }
return outerRadius; return outerRadius;
} }
/**
* Return the outer radius that was manually entered, so not the value that the component received from automatic
* outer radius.
*/
public double getOuterRadiusNoAutomatic() {
return outerRadius;
}
/** /**
* Set the outer radius of the body tube. If the radius is less than the wall thickness, * Set the outer radius of the body tube. If the radius is less than the wall thickness,
@ -136,8 +147,17 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
clearPreset(); clearPreset();
} }
@Override
public boolean usesPreviousCompAutomatic() {
return isOuterRadiusAutomatic() && refComp == getPreviousSymmetricComponent();
}
@Override
public boolean usesNextCompAutomatic() {
return isOuterRadiusAutomatic() && refComp == getNextSymmetricComponent();
}
@Override @Override
protected void loadFromPreset(ComponentPreset preset) { protected void loadFromPreset(ComponentPreset preset) {
this.autoRadius = false; this.autoRadius = false;

View File

@ -69,7 +69,12 @@ public class NoseCone extends Transition implements InsideColorComponent {
public void setForeRadiusAutomatic(boolean b) { public void setForeRadiusAutomatic(boolean b) {
// No-op // No-op
} }
@Override
public boolean usesPreviousCompAutomatic() {
return false;
}
@Override @Override
public double getForeShoulderLength() { public double getForeShoulderLength() {
return 0; return 0;

View File

@ -644,5 +644,15 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
} }
return null; return null;
} }
/**
* Checks whether the component uses the previous symmetric component for its auto diameter.
*/
public abstract boolean usesPreviousCompAutomatic();
/**
* Checks whether the component uses the next symmetric component for its auto diameter.
*/
public abstract boolean usesNextCompAutomatic();
} }

View File

@ -94,6 +94,14 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
return foreRadius; return foreRadius;
} }
/**
* Return the fore radius that was manually entered, so not the value that the component received from automatic
* fore radius.
*/
public double getForeRadiusNoAutomatic() {
return foreRadius;
}
public void setForeRadius(double radius) { public void setForeRadius(double radius) {
if ((this.foreRadius == radius) && (autoForeRadius == false)) if ((this.foreRadius == radius) && (autoForeRadius == false))
return; return;
@ -142,7 +150,13 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
return aftRadius; return aftRadius;
} }
/**
* Return the aft radius that was manually entered, so not the value that the component received from automatic
* zft radius.
*/
public double getAftRadiusNoAutomatic() {
return aftRadius;
}
public void setAftRadius(double radius) { public void setAftRadius(double radius) {
if ((this.aftRadius == radius) && (autoAftRadius2 == false)) if ((this.aftRadius == radius) && (autoAftRadius2 == false))
@ -192,7 +206,15 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
return getForeRadius(); return getForeRadius();
} }
@Override
public boolean usesPreviousCompAutomatic() {
return isForeRadiusAutomatic();
}
@Override
public boolean usesNextCompAutomatic() {
return isAftRadiusAutomatic();
}
//////// Type & shape ///////// //////// Type & shape /////////

View File

@ -15,8 +15,10 @@ import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.UnitSelector; import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.material.Material; import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
@ -24,6 +26,7 @@ import net.sf.openrocket.unit.UnitGroup;
public class BodyTubeConfig extends RocketComponentConfig { public class BodyTubeConfig extends RocketComponentConfig {
private DoubleModel maxLength; private DoubleModel maxLength;
private final JCheckBox checkAutoOuterRadius;
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
public BodyTubeConfig(OpenRocketDocument d, RocketComponent c) { public BodyTubeConfig(OpenRocketDocument d, RocketComponent c) {
@ -58,9 +61,10 @@ public class BodyTubeConfig extends RocketComponentConfig {
//// Automatic //// Automatic
javax.swing.Action outerAutoAction = od.getAutomaticAction(); javax.swing.Action outerAutoAction = od.getAutomaticAction();
JCheckBox check = new JCheckBox(outerAutoAction); checkAutoOuterRadius = new JCheckBox(outerAutoAction);
check.setText(trans.get("BodyTubecfg.checkbox.Automatic")); checkAutoOuterRadius.setText(trans.get("BodyTubecfg.checkbox.Automatic"));
panel.add(check, "skip, span 2, wrap"); panel.add(checkAutoOuterRadius, "skip, span 2, wrap");
updateCheckboxAutoAftRadius();
//// Inner diameter //// Inner diameter
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Innerdiameter"))); panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Innerdiameter")));
@ -87,7 +91,7 @@ public class BodyTubeConfig extends RocketComponentConfig {
panel.add(new BasicSlider(thicknessModel.getSliderModel(0, 0.01)), "w 100lp, wrap 0px"); panel.add(new BasicSlider(thicknessModel.getSliderModel(0, 0.01)), "w 100lp, wrap 0px");
//// Filled //// Filled
check = new JCheckBox(new BooleanModel(component, "Filled")); JCheckBox check = new JCheckBox(new BooleanModel(component, "Filled"));
check.setText(trans.get("BodyTubecfg.checkbox.Filled")); check.setText(trans.get("BodyTubecfg.checkbox.Filled"));
panel.add(check, "skip, span 2, wrap"); panel.add(check, "skip, span 2, wrap");
@ -113,4 +117,33 @@ public class BodyTubeConfig extends RocketComponentConfig {
super.updateFields(); super.updateFields();
} }
/**
* Sets the checkAutoOuterRadius checkbox's enabled state and tooltip text, based on the state of its previous
* component. If there is no next and previous symmetric component, the checkAutoOuterRadius checkbox is disabled.
* If there is still a next or previous component which does not have its auto state enabled, meaning it can still
* serve as a reference component for this component, the auto checkbox is enabled.
*/
private void updateCheckboxAutoAftRadius() {
if (component == null || checkAutoOuterRadius == null) return;
// Disable check button if there is no component to get the diameter from
SymmetricComponent prevComp = ((BodyTube) component).getPreviousSymmetricComponent();
SymmetricComponent nextComp = ((BodyTube) component).getNextSymmetricComponent();
if (prevComp == null && nextComp == null) {
checkAutoOuterRadius.setEnabled(false);
((BodyTube) component).setOuterRadiusAutomatic(false);
checkAutoOuterRadius.setToolTipText(trans.get("BodyTubecfg.checkbox.ttip.Automatic_noReferenceComponent"));
return;
}
if (!(prevComp != null && nextComp == null && prevComp.usesNextCompAutomatic()) &&
!(nextComp != null && prevComp == null && nextComp.usesPreviousCompAutomatic()) &&
!(nextComp != null && prevComp != null && prevComp.usesNextCompAutomatic() && nextComp.usesPreviousCompAutomatic())) {
checkAutoOuterRadius.setEnabled(true);
checkAutoOuterRadius.setToolTipText(trans.get("BodyTubecfg.checkbox.ttip.Automatic"));
} else {
checkAutoOuterRadius.setEnabled(false);
((BodyTube) component).setOuterRadiusAutomatic(false);
checkAutoOuterRadius.setToolTipText(trans.get("BodyTubecfg.checkbox.ttip.Automatic_alreadyAuto"));
}
}
} }

View File

@ -23,6 +23,7 @@ import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.material.Material; import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.NoseCone; import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
@ -36,6 +37,7 @@ public class NoseConeConfig extends RocketComponentConfig {
private JLabel shapeLabel; private JLabel shapeLabel;
private JSpinner shapeSpinner; private JSpinner shapeSpinner;
private JSlider shapeSlider; private JSlider shapeSlider;
private final JCheckBox checkAutoAftRadius;
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
// Prepended to the description from NoseCone.DESCRIPTIONS // Prepended to the description from NoseCone.DESCRIPTIONS
@ -109,10 +111,11 @@ public class NoseConeConfig extends RocketComponentConfig {
panel.add(new UnitSelector(aftRadiusModel), "growx"); panel.add(new UnitSelector(aftRadiusModel), "growx");
panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px"); panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
JCheckBox check = new JCheckBox(aftRadiusModel.getAutomaticAction()); checkAutoAftRadius = new JCheckBox(aftRadiusModel.getAutomaticAction());
//// Automatic //// Automatic
check.setText(trans.get("NoseConeCfg.checkbox.Automatic")); checkAutoAftRadius.setText(trans.get("NoseConeCfg.checkbox.Automatic"));
panel.add(check, "skip, span 2, wrap"); panel.add(checkAutoAftRadius, "skip, span 2, wrap");
updateCheckboxAutoAftRadius();
} }
{//// Wall thickness: {//// Wall thickness:
@ -165,6 +168,30 @@ public class NoseConeConfig extends RocketComponentConfig {
shapeSpinner.setEnabled(e); shapeSpinner.setEnabled(e);
shapeSlider.setEnabled(e); shapeSlider.setEnabled(e);
} }
/**
* Sets the checkAutoAftRadius checkbox's enabled state and tooltip text, based on the state of its next component.
* If there is no next symmetric component or if that component already has its auto checkbox checked, the
* checkAutoAftRadius checkbox is disabled.
*/
private void updateCheckboxAutoAftRadius() {
if (component == null || checkAutoAftRadius == null) return;
// Disable check button if there is no component to get the diameter from
SymmetricComponent nextComp = ((NoseCone) component).getNextSymmetricComponent();
if (nextComp == null) {
checkAutoAftRadius.setEnabled(false);
((NoseCone) component).setAftRadiusAutomatic(false);
checkAutoAftRadius.setToolTipText(trans.get("NoseConeCfg.checkbox.ttip.Automatic_noReferenceComponent"));
return;
}
if (!nextComp.usesPreviousCompAutomatic()) {
checkAutoAftRadius.setEnabled(true);
checkAutoAftRadius.setToolTipText(trans.get("NoseConeCfg.checkbox.ttip.Automatic"));
} else {
checkAutoAftRadius.setEnabled(false);
((NoseCone) component).setAftRadiusAutomatic(false);
checkAutoAftRadius.setToolTipText(trans.get("NoseConeCfg.checkbox.ttip.Automatic_alreadyAuto"));
}
}
} }

View File

@ -21,6 +21,7 @@ import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.material.Material; import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
@ -35,6 +36,8 @@ public class TransitionConfig extends RocketComponentConfig {
private JLabel shapeLabel; private JLabel shapeLabel;
private JSpinner shapeSpinner; private JSpinner shapeSpinner;
private BasicSlider shapeSlider; private BasicSlider shapeSlider;
private final JCheckBox checkAutoAftRadius;
private final JCheckBox checkAutoForeRadius;
private DescriptionArea description; private DescriptionArea description;
@ -120,10 +123,11 @@ public class TransitionConfig extends RocketComponentConfig {
panel.add(new UnitSelector(foreRadiusModel), "growx"); panel.add(new UnitSelector(foreRadiusModel), "growx");
panel.add(new BasicSlider(foreRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px"); panel.add(new BasicSlider(foreRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
final JCheckBox checkbox = new JCheckBox(foreRadiusModel.getAutomaticAction()); checkAutoForeRadius = new JCheckBox(foreRadiusModel.getAutomaticAction());
//// Automatic //// Automatic
checkbox.setText(trans.get("TransitionCfg.checkbox.Automatic")); checkAutoForeRadius.setText(trans.get("TransitionCfg.checkbox.Automatic"));
panel.add(checkbox, "skip, span 2, wrap"); panel.add(checkAutoForeRadius, "skip, span 2, wrap");
updateCheckboxAutoForeRadius();
} }
{ //// Aft diameter: { //// Aft diameter:
@ -139,10 +143,11 @@ public class TransitionConfig extends RocketComponentConfig {
panel.add(new UnitSelector(aftRadiusModel), "growx"); panel.add(new UnitSelector(aftRadiusModel), "growx");
panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px"); panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
final JCheckBox aftRadiusCheckbox = new JCheckBox(aftRadiusModel.getAutomaticAction()); checkAutoAftRadius = new JCheckBox(aftRadiusModel.getAutomaticAction());
//// Automatic //// Automatic
aftRadiusCheckbox.setText(trans.get("TransitionCfg.checkbox.Automatic")); checkAutoAftRadius.setText(trans.get("TransitionCfg.checkbox.Automatic"));
panel.add(aftRadiusCheckbox, "skip, span 2, wrap"); panel.add(checkAutoAftRadius, "skip, span 2, wrap");
updateCheckboxAutoAftRadius();
} }
{ /// Wall thickness: { /// Wall thickness:
@ -194,5 +199,57 @@ public class TransitionConfig extends RocketComponentConfig {
shapeSpinner.setEnabled(e); shapeSpinner.setEnabled(e);
shapeSlider.setEnabled(e); shapeSlider.setEnabled(e);
} }
/**
* Sets the checkAutoAftRadius checkbox's enabled state and tooltip text, based on the state of its next component.
* If there is no next symmetric component or if that component already has its auto checkbox checked, the
* checkAutoAftRadius checkbox is disabled.
*/
private void updateCheckboxAutoAftRadius() {
if (component == null || checkAutoAftRadius == null) return;
// Disable check button if there is no component to get the diameter from
SymmetricComponent nextComp = ((Transition) component).getNextSymmetricComponent();
if (nextComp == null) {
checkAutoAftRadius.setEnabled(false);
((Transition) component).setAftRadiusAutomatic(false);
checkAutoAftRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic_noReferenceComponent"));
return;
}
if (!nextComp.usesPreviousCompAutomatic()) {
checkAutoAftRadius.setEnabled(true);
checkAutoAftRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic"));
} else {
checkAutoAftRadius.setEnabled(false);
((Transition) component).setAftRadiusAutomatic(false);
checkAutoAftRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic_alreadyAuto"));
}
}
/**
* Sets the checkAutoForeRadius checkbox's enabled state and tooltip text, based on the state of its next component.
* If there is no next symmetric component or if that component already has its auto checkbox checked, the
* checkAutoForeRadius checkbox is disabled.
*/
private void updateCheckboxAutoForeRadius() {
if (component == null || checkAutoForeRadius == null) return;
// Disable check button if there is no component to get the diameter from
SymmetricComponent prevComp = ((Transition) component).getPreviousSymmetricComponent();
if (prevComp == null) {
checkAutoForeRadius.setEnabled(false);
((Transition) component).setForeRadiusAutomatic(false);
checkAutoForeRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic_noReferenceComponent"));
return;
}
if (!prevComp.usesNextCompAutomatic()) {
checkAutoForeRadius.setEnabled(true);
checkAutoForeRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic"));
} else {
checkAutoForeRadius.setEnabled(false);
((Transition) component).setForeRadiusAutomatic(false);
checkAutoForeRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic_alreadyAuto"));
}
}
} }