Data model refactoring
This commit is contained in:
parent
4c48ec48c9
commit
170ce13c05
@ -1361,6 +1361,15 @@ RecoveryDevice.DeployEvent.CURRENT_STAGE_SEPARATION = Current stage separation
|
||||
RecoveryDevice.DeployEvent.LOWER_STAGE_SEPARATION = Lower stage separation
|
||||
RecoveryDevice.DeployEvent.NEVER = Never
|
||||
|
||||
RecoveryDevice.DeployEvent.short.LAUNCH = Launch
|
||||
RecoveryDevice.DeployEvent.short.EJECTION = Ejection charge
|
||||
RecoveryDevice.DeployEvent.short.APOGEE = Apogee
|
||||
RecoveryDevice.DeployEvent.short.ALTITUDE = Altitude
|
||||
RecoveryDevice.DeployEvent.short.CURRENT_STAGE_SEPARATION = Current stage separation
|
||||
RecoveryDevice.DeployEvent.short.LOWER_STAGE_SEPARATION = Lower stage separation
|
||||
RecoveryDevice.DeployEvent.short.NEVER = Never
|
||||
|
||||
|
||||
! FlightEvent
|
||||
FlightEvent.Type.LAUNCH = Launch
|
||||
FlightEvent.Type.IGNITION = Motor ignition
|
||||
@ -1828,7 +1837,21 @@ MotorConfigurationPanel.btn.selectIgnition = Select ignition
|
||||
MotorConfigurationPanel.btn.resetIgnition = Reset ignition
|
||||
|
||||
MotorConfigurationTableModel.table.ignition.default = Default ({0})
|
||||
RecoveryConfigurationPanel.table.deployment.default = Default ({0})
|
||||
SeparationConfigurationPanel.table.separation.default = Default ({0})
|
||||
|
||||
IgnitionSelectionDialog.opt.title = Which flight configurations are affected:
|
||||
IgnitionSelectionDialog.opt.default = Change the default ignition event for this motor
|
||||
IgnitionSelectionDialog.opt.override = Override for the {0} flight configuration only
|
||||
|
||||
DeploymentSelectionDialog.opt.title = Which flight configurations are affected:
|
||||
DeploymentSelectionDialog.opt.default = Change the default deployment event for this recovery device
|
||||
DeploymentSelectionDialog.opt.override = Override for the {0} flight configuration only
|
||||
|
||||
SeparationSelectionDialog.lbl.separation = Stage separation at:
|
||||
SeparationSelectionDialog.opt.title = Which flight configurations are affected:
|
||||
SeparationSelectionDialog.opt.default = Change the default separation event for this stage
|
||||
SeparationSelectionDialog.opt.override = Override for the {0} flight configuration only
|
||||
|
||||
MotorConfigurationPanel.description = <b>Select the motors and motor ignition events of your rocket.</b><br> <em>Motor mounts:</em> Select which components function as motor mounts.<br> <em>Motor configurations:</em> Select the motor and ignition event for each motor mount.
|
||||
|
||||
|
@ -4,9 +4,9 @@ import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.EventListener;
|
||||
|
||||
import net.sf.openrocket.appearance.DecalImage;
|
||||
import net.sf.openrocket.util.StateChangeListener;
|
||||
|
||||
|
||||
class ResourceDecalImage implements DecalImage {
|
||||
@ -38,12 +38,12 @@ class ResourceDecalImage implements DecalImage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeListener(EventListener listener) {
|
||||
public void addChangeListener(StateChangeListener listener) {
|
||||
//Unimplemented, this can not change
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChangeListener(EventListener listener) {
|
||||
public void removeChangeListener(StateChangeListener listener) {
|
||||
//Unimplemented, this can not change
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ public class GeneralRocketSaver {
|
||||
*
|
||||
* @param progress int value between 0 and 100 representing percent complete.
|
||||
*/
|
||||
public void setProgress( int progress );
|
||||
public void setProgress(int progress);
|
||||
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ public class GeneralRocketSaver {
|
||||
* @throws IOException in case of an I/O error.
|
||||
*/
|
||||
public final void save(File dest, OpenRocketDocument document, StorageOptions options) throws IOException {
|
||||
save( dest, document, options, null );
|
||||
save(dest, document, options, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,8 +75,8 @@ public class GeneralRocketSaver {
|
||||
* @param progress a SavingProgress object used to provide progress information
|
||||
* @throws IOException in case of an I/O error.
|
||||
*/
|
||||
public final void save(File dest, OpenRocketDocument doc, SavingProgress progress ) throws IOException {
|
||||
save( dest, doc, doc.getDefaultStorageOptions(), progress );
|
||||
public final void save(File dest, OpenRocketDocument doc, SavingProgress progress) throws IOException {
|
||||
save(dest, doc, doc.getDefaultStorageOptions(), progress);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,19 +88,19 @@ public class GeneralRocketSaver {
|
||||
* @param progress a SavingProgress object used to provide progress information
|
||||
* @throws IOException in case of an I/O error.
|
||||
*/
|
||||
public final void save(File dest, OpenRocketDocument doc, StorageOptions opts, SavingProgress progress ) throws IOException {
|
||||
public final void save(File dest, OpenRocketDocument doc, StorageOptions opts, SavingProgress progress) throws IOException {
|
||||
|
||||
// This method is the core operational method. It saves the document into a new (hopefully unique)
|
||||
// file, then if the save is successful, it will copy the file over the old one.
|
||||
|
||||
// Write to a temporary file in the same directory as the specified file.
|
||||
File temporaryNewFile = File.createTempFile("ORSave", ".tmp", dest.getParentFile() );
|
||||
File temporaryNewFile = File.createTempFile("ORSave", ".tmp", dest.getParentFile());
|
||||
|
||||
OutputStream s = new BufferedOutputStream( new FileOutputStream(temporaryNewFile));
|
||||
OutputStream s = new BufferedOutputStream(new FileOutputStream(temporaryNewFile));
|
||||
|
||||
if ( progress != null ) {
|
||||
if (progress != null) {
|
||||
long estimatedSize = this.estimateFileSize(doc, opts);
|
||||
s = new ProgressOutputStream( s, estimatedSize, progress );
|
||||
s = new ProgressOutputStream(s, estimatedSize, progress);
|
||||
}
|
||||
try {
|
||||
save(dest.getName(), s, doc, opts);
|
||||
@ -111,17 +111,17 @@ public class GeneralRocketSaver {
|
||||
// Move the temporary new file over the specified file.
|
||||
|
||||
boolean destExists = dest.exists();
|
||||
File oldBackupFile = new File( dest.getParentFile(), dest.getName() + "-bak");
|
||||
File oldBackupFile = new File(dest.getParentFile(), dest.getName() + "-bak");
|
||||
|
||||
if ( destExists ) {
|
||||
if (destExists) {
|
||||
dest.renameTo(oldBackupFile);
|
||||
}
|
||||
// since we created the temporary new file in the same directory as the dest file,
|
||||
// it is on the same filesystem, so File.renameTo will work just fine.
|
||||
boolean success = temporaryNewFile.renameTo(dest);
|
||||
|
||||
if ( success ) {
|
||||
if ( destExists ) {
|
||||
if (success) {
|
||||
if (destExists) {
|
||||
oldBackupFile.delete();
|
||||
}
|
||||
}
|
||||
@ -137,10 +137,10 @@ public class GeneralRocketSaver {
|
||||
* @return the estimated number of bytes the storage would take.
|
||||
*/
|
||||
public long estimateFileSize(OpenRocketDocument doc, StorageOptions options) {
|
||||
if ( options.getFileType() == StorageOptions.FileType.ROCKSIM ) {
|
||||
if (options.getFileType() == StorageOptions.FileType.ROCKSIM) {
|
||||
return new RocksimSaver().estimateFileSize(doc, options);
|
||||
} else {
|
||||
return new OpenRocketSaver().estimateFileSize(doc,options);
|
||||
return new OpenRocketSaver().estimateFileSize(doc, options);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ public class GeneralRocketSaver {
|
||||
// For now, we don't save decal inforamtion in ROCKSIM files, so don't do anything
|
||||
// which follows.
|
||||
// TODO - add support for decals in ROCKSIM files?
|
||||
if ( options.getFileType() == FileType.ROCKSIM ) {
|
||||
if (options.getFileType() == FileType.ROCKSIM) {
|
||||
saveInternal(output, document, options);
|
||||
output.close();
|
||||
return;
|
||||
@ -158,12 +158,12 @@ public class GeneralRocketSaver {
|
||||
Set<DecalImage> usedDecals = new TreeSet<DecalImage>();
|
||||
|
||||
// Look for all decals used in the rocket.
|
||||
for( RocketComponent c : document.getRocket() ) {
|
||||
if ( c.getAppearance() == null ) {
|
||||
for (RocketComponent c : document.getRocket()) {
|
||||
if (c.getAppearance() == null) {
|
||||
continue;
|
||||
}
|
||||
Appearance ap = c.getAppearance();
|
||||
if ( ap.getTexture() == null ) {
|
||||
if (ap.getTexture() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -172,10 +172,10 @@ public class GeneralRocketSaver {
|
||||
usedDecals.add(decal.getImage());
|
||||
}
|
||||
|
||||
saveAllPartsZipFile(fileName, output, document, options, usedDecals);
|
||||
saveAllPartsZipFile(output, document, options, usedDecals);
|
||||
}
|
||||
|
||||
public void saveAllPartsZipFile(String fileName, OutputStream output, OpenRocketDocument document, StorageOptions options, Set<DecalImage> decals) throws IOException {
|
||||
public void saveAllPartsZipFile(OutputStream output, OpenRocketDocument document, StorageOptions options, Set<DecalImage> decals) throws IOException {
|
||||
|
||||
// Open a zip stream to write to.
|
||||
ZipOutputStream zos = new ZipOutputStream(output);
|
||||
@ -184,14 +184,14 @@ public class GeneralRocketSaver {
|
||||
try {
|
||||
|
||||
|
||||
ZipEntry mainFile = new ZipEntry(fileName);
|
||||
ZipEntry mainFile = new ZipEntry("rocket.ork");
|
||||
zos.putNextEntry(mainFile);
|
||||
saveInternal(zos,document,options);
|
||||
saveInternal(zos, document, options);
|
||||
zos.closeEntry();
|
||||
|
||||
// Now we write out all the decal images files.
|
||||
|
||||
for( DecalImage image : decals ) {
|
||||
for (DecalImage image : decals) {
|
||||
|
||||
String name = image.getName();
|
||||
ZipEntry decal = new ZipEntry(name);
|
||||
@ -200,7 +200,7 @@ public class GeneralRocketSaver {
|
||||
InputStream is = image.getBytes();
|
||||
int bytesRead = 0;
|
||||
byte[] buffer = new byte[2048];
|
||||
while( (bytesRead = is.read(buffer)) > 0 ) {
|
||||
while ((bytesRead = is.read(buffer)) > 0) {
|
||||
zos.write(buffer, 0, bytesRead);
|
||||
}
|
||||
zos.closeEntry();
|
||||
@ -219,7 +219,7 @@ public class GeneralRocketSaver {
|
||||
private void saveInternal(OutputStream output, OpenRocketDocument document, StorageOptions options)
|
||||
throws IOException {
|
||||
|
||||
if ( options.getFileType() == StorageOptions.FileType.ROCKSIM ) {
|
||||
if (options.getFileType() == StorageOptions.FileType.ROCKSIM) {
|
||||
new RocksimSaver().save(output, document, options);
|
||||
} else {
|
||||
new OpenRocketSaver().save(output, document, options);
|
||||
@ -232,7 +232,7 @@ public class GeneralRocketSaver {
|
||||
private long bytesWritten = 0;
|
||||
private SavingProgress progressCallback;
|
||||
|
||||
ProgressOutputStream( OutputStream ostream, long estimatedSize, SavingProgress progressCallback ) {
|
||||
ProgressOutputStream(OutputStream ostream, long estimatedSize, SavingProgress progressCallback) {
|
||||
super(ostream);
|
||||
this.estimatedSize = estimatedSize;
|
||||
this.progressCallback = progressCallback;
|
||||
@ -262,8 +262,8 @@ public class GeneralRocketSaver {
|
||||
private void updateProgress() {
|
||||
if (progressCallback != null) {
|
||||
int p = 50;
|
||||
if ( estimatedSize > 0 ) {
|
||||
p = (int) Math.floor( bytesWritten * 100.0 / estimatedSize );
|
||||
if (estimatedSize > 0) {
|
||||
p = (int) Math.floor(bytesWritten * 100.0 / estimatedSize);
|
||||
p = MathUtil.clamp(p, 0, 100);
|
||||
}
|
||||
progressCallback.setProgress(p);
|
||||
|
@ -40,22 +40,4 @@ public abstract class RocketSaver {
|
||||
* @return the estimated number of bytes the storage would take.
|
||||
*/
|
||||
public abstract long estimateFileSize(OpenRocketDocument doc, StorageOptions options);
|
||||
|
||||
public static String escapeXML(String s) {
|
||||
|
||||
s = s.replace("&", "&");
|
||||
s = s.replace("<", "<");
|
||||
s = s.replace(">", ">");
|
||||
s = s.replace("\"",""");
|
||||
s = s.replace("'", "'");
|
||||
|
||||
for (int i=0; i < s.length(); i++) {
|
||||
char n = s.charAt(i);
|
||||
if (((n < 32) && (n != 9) && (n != 10) && (n != 13)) || (n == 127)) {
|
||||
s = s.substring(0,i) + "&#" + ((int)n) + ";" + s.substring(i+1);
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ public class OpenRocketSaver extends RocketSaver {
|
||||
writeln("<simulation status=\"" + enumToXMLName(simulation.getStatus()) + "\">");
|
||||
indent++;
|
||||
|
||||
writeln("<name>" + escapeXML(simulation.getName()) + "</name>");
|
||||
writeln("<name>" + TextUtil.escapeXML(simulation.getName()) + "</name>");
|
||||
// TODO: MEDIUM: Other simulators/calculators
|
||||
|
||||
writeln("<simulator>RK4Simulator</simulator>");
|
||||
@ -392,7 +392,7 @@ public class OpenRocketSaver extends RocketSaver {
|
||||
|
||||
|
||||
for (String s : simulation.getSimulationListeners()) {
|
||||
writeElement("listener", escapeXML(s));
|
||||
writeElement("listener", TextUtil.escapeXML(s));
|
||||
}
|
||||
|
||||
// Write basic simulation data
|
||||
@ -423,7 +423,7 @@ public class OpenRocketSaver extends RocketSaver {
|
||||
indent++;
|
||||
|
||||
for (Warning w : data.getWarningSet()) {
|
||||
writeElement("warning", escapeXML(w.toString()));
|
||||
writeElement("warning", TextUtil.escapeXML(w.toString()));
|
||||
}
|
||||
|
||||
// Check whether to store data
|
||||
@ -471,7 +471,7 @@ public class OpenRocketSaver extends RocketSaver {
|
||||
// Build the <databranch> tag
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<databranch name=\"");
|
||||
sb.append(escapeXML(branch.getBranchName()));
|
||||
sb.append(TextUtil.escapeXML(branch.getBranchName()));
|
||||
|
||||
// Kevins version where typekeys are used
|
||||
/*
|
||||
@ -487,7 +487,7 @@ public class OpenRocketSaver extends RocketSaver {
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (i > 0)
|
||||
sb.append(",");
|
||||
sb.append(escapeXML(types[i].getName()));
|
||||
sb.append(TextUtil.escapeXML(types[i].getName()));
|
||||
}
|
||||
sb.append("\">");
|
||||
writeln(sb.toString());
|
||||
|
@ -15,12 +15,29 @@ import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
class DeploymentConfigurationHandler extends AbstractElementHandler {
|
||||
private final RecoveryDevice recoveryDevice;
|
||||
private DeploymentConfiguration config;
|
||||
|
||||
public DeploymentConfigurationHandler( RecoveryDevice recoveryDevice, DocumentLoadingContext context ) {
|
||||
this.recoveryDevice = recoveryDevice;
|
||||
config = new DeploymentConfiguration();
|
||||
private final RecoveryDevice recoveryDevice;
|
||||
|
||||
private DeployEvent event = null;
|
||||
private double delay = Double.NaN;
|
||||
private double altitude = Double.NaN;
|
||||
|
||||
public DeploymentConfigurationHandler(RecoveryDevice component, DocumentLoadingContext context) {
|
||||
this.recoveryDevice = component;
|
||||
}
|
||||
|
||||
public DeploymentConfiguration getConfiguration(DeploymentConfiguration def) {
|
||||
DeploymentConfiguration config = def.clone();
|
||||
if (event != null) {
|
||||
config.setDeployEvent(event);
|
||||
}
|
||||
if (!Double.isNaN(delay)) {
|
||||
config.setDeployDelay(delay);
|
||||
}
|
||||
if (!Double.isNaN(altitude)) {
|
||||
config.setDeployAltitude(altitude);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -35,19 +52,18 @@ class DeploymentConfigurationHandler extends AbstractElementHandler {
|
||||
|
||||
content = content.trim();
|
||||
|
||||
if ( "deployevent".equals(element) ) {
|
||||
DeployEvent type = (DeployEvent) DocumentConfig.findEnum(content, DeployEvent.class);
|
||||
if ( type == null ) {
|
||||
if ("deployevent".equals(element)) {
|
||||
event = (DeployEvent) DocumentConfig.findEnum(content, DeployEvent.class);
|
||||
if (event == null) {
|
||||
warnings.add(Warning.FILE_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
config.setDeployEvent( type );
|
||||
return;
|
||||
} else if ( "deployaltitude".equals(element) ) {
|
||||
config.setDeployAltitude( Double.parseDouble(content));
|
||||
} else if ("deploydelay".equals(element)) {
|
||||
delay = parseDouble(content, warnings, Warning.FILE_INVALID_PARAMETER);
|
||||
return;
|
||||
} else if ( "deploydelay".equals(element) ) {
|
||||
config.setDeployDelay( Double.parseDouble(content));
|
||||
} else if ("deployaltitude".equals(element)) {
|
||||
altitude = parseDouble(content, warnings, Warning.FILE_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
super.closeElement(element, attributes, content, warnings);
|
||||
@ -57,7 +73,8 @@ class DeploymentConfigurationHandler extends AbstractElementHandler {
|
||||
@Override
|
||||
public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings) throws SAXException {
|
||||
String configId = attributes.get("configid");
|
||||
recoveryDevice.setFlightConfiguration(configId, config);
|
||||
DeploymentConfiguration def = recoveryDevice.getDeploymentConfiguration().getDefault();
|
||||
recoveryDevice.getDeploymentConfiguration().set(configId, getConfiguration(def));
|
||||
}
|
||||
|
||||
}
|
@ -10,6 +10,7 @@ import net.sf.openrocket.rocketcomponent.BodyComponent;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.Bulkhead;
|
||||
import net.sf.openrocket.rocketcomponent.CenteringRing;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.EngineBlock;
|
||||
@ -47,7 +48,7 @@ import net.sf.openrocket.util.Reflection;
|
||||
class DocumentConfig {
|
||||
|
||||
/* Remember to update OpenRocketSaver as well! */
|
||||
public static final String[] SUPPORTED_VERSIONS = { "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6"};
|
||||
public static final String[] SUPPORTED_VERSIONS = { "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6" };
|
||||
|
||||
/**
|
||||
* Divisor used in converting an integer version to the point-represented version.
|
||||
@ -327,12 +328,15 @@ class DocumentConfig {
|
||||
"auto",
|
||||
Reflection.findMethod(RecoveryDevice.class, "setCDAutomatic", boolean.class)));
|
||||
setters.put("RecoveryDevice:deployevent", new EnumSetter<DeployEvent>(
|
||||
Reflection.findMethod(RecoveryDevice.class, "setDefaultDeployEvent", DeployEvent.class),
|
||||
Reflection.findMethod(RecoveryDevice.class, "getDeploymentConfiguration"),
|
||||
Reflection.findMethod(DeploymentConfiguration.class, "setDeployEvent", DeployEvent.class),
|
||||
DeployEvent.class));
|
||||
setters.put("RecoveryDevice:deployaltitude", new DoubleSetter(
|
||||
Reflection.findMethod(RecoveryDevice.class, "setDefaultDeployAltitude", double.class)));
|
||||
Reflection.findMethod(RecoveryDevice.class, "getDeploymentConfiguration"),
|
||||
Reflection.findMethod(DeploymentConfiguration.class, "setDeployAltitude", double.class)));
|
||||
setters.put("RecoveryDevice:deploydelay", new DoubleSetter(
|
||||
Reflection.findMethod(RecoveryDevice.class, "setDefaultDeployDelay", double.class)));
|
||||
Reflection.findMethod(RecoveryDevice.class, "getDeploymentConfiguration"),
|
||||
Reflection.findMethod(DeploymentConfiguration.class, "setDeployDelay", double.class)));
|
||||
setters.put("RecoveryDevice:material", new MaterialSetter(
|
||||
Reflection.findMethod(RecoveryDevice.class, "setMaterial", Material.class),
|
||||
Material.Type.SURFACE));
|
||||
@ -368,10 +372,12 @@ class DocumentConfig {
|
||||
|
||||
// Stage
|
||||
setters.put("Stage:separationevent", new EnumSetter<StageSeparationConfiguration.SeparationEvent>(
|
||||
Reflection.findMethod(Stage.class, "setDefaultSeparationEvent", StageSeparationConfiguration.SeparationEvent.class),
|
||||
Reflection.findMethod(Stage.class, "getStageSeparationConfiguration"),
|
||||
Reflection.findMethod(StageSeparationConfiguration.class, "setSeparationEvent", StageSeparationConfiguration.SeparationEvent.class),
|
||||
StageSeparationConfiguration.SeparationEvent.class));
|
||||
setters.put("Stage:separationdelay", new DoubleSetter(
|
||||
Reflection.findMethod(Stage.class, "setDefaultSeparationDelay", double.class)));
|
||||
Reflection.findMethod(Stage.class, "getStageSeparationConfiguration"),
|
||||
Reflection.findMethod(StageSeparationConfiguration.class, "setSeparationDelay", double.class)));
|
||||
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,15 @@ import java.util.HashMap;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.Warning;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Reflection;
|
||||
import net.sf.openrocket.util.Reflection.Method;
|
||||
|
||||
//// DoubleSetter - sets a double value or (alternatively) if a specific string is encountered
|
||||
//// calls a setXXX(boolean) method.
|
||||
class DoubleSetter implements Setter {
|
||||
private final Reflection.Method configGetter;
|
||||
private final Reflection.Method setMethod;
|
||||
private final String specialString;
|
||||
private final Reflection.Method specialMethod;
|
||||
@ -21,6 +24,7 @@ class DoubleSetter implements Setter {
|
||||
*/
|
||||
public DoubleSetter(Reflection.Method set) {
|
||||
this.setMethod = set;
|
||||
this.configGetter = null;
|
||||
this.specialString = null;
|
||||
this.specialMethod = null;
|
||||
this.multiplier = 1.0;
|
||||
@ -33,6 +37,7 @@ class DoubleSetter implements Setter {
|
||||
*/
|
||||
public DoubleSetter(Reflection.Method set, double mul) {
|
||||
this.setMethod = set;
|
||||
this.configGetter = null;
|
||||
this.specialString = null;
|
||||
this.specialMethod = null;
|
||||
this.multiplier = mul;
|
||||
@ -49,12 +54,27 @@ class DoubleSetter implements Setter {
|
||||
public DoubleSetter(Reflection.Method set, String special,
|
||||
Reflection.Method specialMethod) {
|
||||
this.setMethod = set;
|
||||
this.configGetter = null;
|
||||
this.specialString = special;
|
||||
this.specialMethod = specialMethod;
|
||||
this.multiplier = 1.0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a double value of the default configuration of a FlightConfiguration object.
|
||||
*
|
||||
* @param configGetter getter method for the FlightConfiguration object
|
||||
* @param setter setter method for the configuration object
|
||||
*/
|
||||
public DoubleSetter(Method configGetter, Method setter) {
|
||||
this.setMethod = setter;
|
||||
this.configGetter = configGetter;
|
||||
this.specialString = null;
|
||||
this.specialMethod = null;
|
||||
this.multiplier = 1.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(RocketComponent c, String s, HashMap<String, String> attributes,
|
||||
WarningSet warnings) {
|
||||
@ -70,7 +90,14 @@ class DoubleSetter implements Setter {
|
||||
// Normal case
|
||||
try {
|
||||
double d = Double.parseDouble(s);
|
||||
|
||||
if (configGetter == null) {
|
||||
setMethod.invoke(c, d * multiplier);
|
||||
} else {
|
||||
FlightConfiguration<?> config = (FlightConfiguration<?>) configGetter.invoke(c);
|
||||
Object obj = config.getDefault();
|
||||
setMethod.invoke(obj, d * multiplier);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
warnings.add(Warning.FILE_INVALID_PARAMETER);
|
||||
}
|
||||
|
@ -4,16 +4,24 @@ import java.util.HashMap;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.Warning;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Reflection;
|
||||
import net.sf.openrocket.util.Reflection.Method;
|
||||
|
||||
//// EnumSetter - sets a generic enum type
|
||||
class EnumSetter<T extends Enum<T>> implements Setter {
|
||||
private final Reflection.Method configurationGetter;
|
||||
private final Reflection.Method setter;
|
||||
private final Class<T> enumClass;
|
||||
|
||||
public EnumSetter(Reflection.Method set, Class<T> enumClass) {
|
||||
this.setter = set;
|
||||
public EnumSetter(Reflection.Method setter, Class<T> enumClass) {
|
||||
this(null, setter, enumClass);
|
||||
}
|
||||
|
||||
public EnumSetter(Method configurationGetter, Method setter, Class<T> enumClass) {
|
||||
this.configurationGetter = configurationGetter;
|
||||
this.setter = setter;
|
||||
this.enumClass = enumClass;
|
||||
}
|
||||
|
||||
@ -27,6 +35,12 @@ class EnumSetter<T extends Enum<T>> implements Setter {
|
||||
return;
|
||||
}
|
||||
|
||||
if (configurationGetter == null) {
|
||||
setter.invoke(c, setEnum);
|
||||
} else {
|
||||
FlightConfiguration<?> config = (FlightConfiguration<?>) configurationGetter.invoke(c);
|
||||
Object obj = config.getDefault();
|
||||
setter.invoke(obj, setEnum);
|
||||
}
|
||||
}
|
||||
}
|
@ -9,21 +9,19 @@ import net.sf.openrocket.file.DocumentLoadingContext;
|
||||
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
|
||||
import net.sf.openrocket.file.simplesax.ElementHandler;
|
||||
import net.sf.openrocket.file.simplesax.PlainTextHandler;
|
||||
import net.sf.openrocket.rocketcomponent.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration.IgnitionEvent;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
class IgnitionConfigurationHandler extends AbstractElementHandler {
|
||||
/** File version where latest digest format was introduced */
|
||||
private static final int MOTOR_DIGEST_VERSION = 104;
|
||||
|
||||
private final DocumentLoadingContext context;
|
||||
|
||||
private Double ignitionDelay = null;
|
||||
private MotorConfiguration.IgnitionEvent ignitionEvent = null;
|
||||
private IgnitionEvent ignitionEvent = null;
|
||||
|
||||
|
||||
public IgnitionConfigurationHandler(DocumentLoadingContext context) {
|
||||
this.context = context;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -34,13 +32,17 @@ class IgnitionConfigurationHandler extends AbstractElementHandler {
|
||||
}
|
||||
|
||||
|
||||
public Double getIgnitionDelay() {
|
||||
return ignitionDelay;
|
||||
public IgnitionConfiguration getConfiguration(IgnitionConfiguration def) {
|
||||
IgnitionConfiguration config = def.clone();
|
||||
if (ignitionEvent != null) {
|
||||
config.setIgnitionEvent(ignitionEvent);
|
||||
}
|
||||
if (ignitionDelay != null) {
|
||||
config.setIgnitionDelay(ignitionDelay);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
public MotorConfiguration.IgnitionEvent getIgnitionEvent() {
|
||||
return ignitionEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeElement(String element, HashMap<String, String> attributes,
|
||||
@ -50,7 +52,7 @@ class IgnitionConfigurationHandler extends AbstractElementHandler {
|
||||
|
||||
if (element.equals("ignitionevent")) {
|
||||
|
||||
for (MotorConfiguration.IgnitionEvent e : MotorConfiguration.IgnitionEvent.values()) {
|
||||
for (IgnitionEvent e : IgnitionEvent.values()) {
|
||||
if (e.name().toLowerCase(Locale.ENGLISH).replaceAll("_", "").equals(content)) {
|
||||
ignitionEvent = e;
|
||||
break;
|
||||
|
@ -9,7 +9,6 @@ import net.sf.openrocket.file.DocumentLoadingContext;
|
||||
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
|
||||
import net.sf.openrocket.file.simplesax.ElementHandler;
|
||||
import net.sf.openrocket.file.simplesax.PlainTextHandler;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
@ -65,9 +64,11 @@ class MotorMountHandler extends AbstractElementHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
Motor motor = motorHandler.getMotor(warnings);
|
||||
mount.setMotor(id, motor);
|
||||
mount.setMotorDelay(id, motorHandler.getDelay(warnings));
|
||||
MotorConfiguration config = new MotorConfiguration();
|
||||
config.setMotor(motorHandler.getMotor(warnings));
|
||||
config.setEjectionDelay(motorHandler.getDelay(warnings));
|
||||
mount.getMotorConfiguration().set(id, config);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -77,9 +78,9 @@ class MotorMountHandler extends AbstractElementHandler {
|
||||
warnings.add(Warning.fromString("Illegal motor specification, ignoring."));
|
||||
return;
|
||||
}
|
||||
MotorConfiguration motorConfig = mount.getFlightConfiguration(id);
|
||||
motorConfig.setIgnitionEvent(ignitionConfigHandler.getIgnitionEvent());
|
||||
motorConfig.setIgnitionDelay(ignitionConfigHandler.getIgnitionDelay());
|
||||
|
||||
IgnitionConfiguration def = mount.getIgnitionConfiguration().getDefault();
|
||||
mount.getIgnitionConfiguration().set(id, ignitionConfigHandler.getConfiguration(def));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -95,7 +96,7 @@ class MotorMountHandler extends AbstractElementHandler {
|
||||
warnings.add(Warning.fromString("Unknown ignition event type '" + content + "', ignoring."));
|
||||
return;
|
||||
}
|
||||
mount.setDefaultIgnitionEvent(event);
|
||||
mount.getIgnitionConfiguration().getDefault().setIgnitionEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -107,7 +108,7 @@ class MotorMountHandler extends AbstractElementHandler {
|
||||
warnings.add(Warning.fromString("Illegal ignition delay specified, ignoring."));
|
||||
return;
|
||||
}
|
||||
mount.setDefaultIgnitionDelay(d);
|
||||
mount.getIgnitionConfiguration().getDefault().setIgnitionDelay(d);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -16,13 +16,27 @@ import org.xml.sax.SAXException;
|
||||
|
||||
class StageSeparationConfigurationHandler extends AbstractElementHandler {
|
||||
private final Stage stage;
|
||||
private StageSeparationConfiguration config;
|
||||
|
||||
public StageSeparationConfigurationHandler( Stage stage, DocumentLoadingContext context ) {
|
||||
private SeparationEvent event = null;
|
||||
private double delay = Double.NaN;
|
||||
|
||||
public StageSeparationConfigurationHandler(Stage stage, DocumentLoadingContext context) {
|
||||
this.stage = stage;
|
||||
config = new StageSeparationConfiguration();
|
||||
}
|
||||
|
||||
|
||||
public StageSeparationConfiguration getConfiguration(StageSeparationConfiguration def) {
|
||||
StageSeparationConfiguration config = def.clone();
|
||||
if (event != null) {
|
||||
config.setSeparationEvent(event);
|
||||
}
|
||||
if (!Double.isNaN(delay)) {
|
||||
config.setSeparationDelay(delay);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ElementHandler openElement(String element, HashMap<String, String> attributes, WarningSet warnings)
|
||||
throws SAXException {
|
||||
@ -35,16 +49,15 @@ class StageSeparationConfigurationHandler extends AbstractElementHandler {
|
||||
|
||||
content = content.trim();
|
||||
|
||||
if ( "separationevent".equals(element) ) {
|
||||
SeparationEvent type = (SeparationEvent) DocumentConfig.findEnum(content, SeparationEvent.class);
|
||||
if ( type == null ) {
|
||||
if ("separationevent".equals(element)) {
|
||||
event = (SeparationEvent) DocumentConfig.findEnum(content, SeparationEvent.class);
|
||||
if (event == null) {
|
||||
warnings.add(Warning.FILE_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
config.setSeparationEvent( type );
|
||||
return;
|
||||
} else if ( "separationdelay".equals(element) ) {
|
||||
config.setSeparationDelay( Double.parseDouble(content));
|
||||
} else if ("separationdelay".equals(element)) {
|
||||
delay = parseDouble(content, warnings, Warning.FILE_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
super.closeElement(element, attributes, content, warnings);
|
||||
@ -54,7 +67,8 @@ class StageSeparationConfigurationHandler extends AbstractElementHandler {
|
||||
@Override
|
||||
public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings) throws SAXException {
|
||||
String configId = attributes.get("configid");
|
||||
stage.setFlightConfiguration(configId, config);
|
||||
StageSeparationConfiguration def = stage.getStageSeparationConfiguration().getDefault();
|
||||
stage.getStageSeparationConfiguration().set(configId, getConfiguration(def));
|
||||
}
|
||||
|
||||
}
|
@ -21,37 +21,38 @@ public class RecoveryDeviceSaver extends MassObjectSaver {
|
||||
elements.add("<cd>auto</cd>");
|
||||
else
|
||||
elements.add("<cd>" + dev.getCD() + "</cd>");
|
||||
|
||||
DeploymentConfiguration defaultConfig = dev.getDefaultFlightConfiguration();
|
||||
elements.addAll( deploymentConfiguration(defaultConfig, false));
|
||||
elements.add(materialParam(dev.getMaterial()));
|
||||
|
||||
// NOTE: Default config must be BEFORE overridden config for proper backward compatibility later on
|
||||
DeploymentConfiguration defaultConfig = dev.getDeploymentConfiguration().getDefault();
|
||||
elements.addAll(deploymentConfiguration(defaultConfig, false));
|
||||
|
||||
Rocket rocket = c.getRocket();
|
||||
// Note - getFlightConfigurationIDs returns at least one element. The first element
|
||||
// is null and means "default".
|
||||
String[] configs = rocket.getFlightConfigurationIDs();
|
||||
if ( configs.length > 1 ) {
|
||||
if (configs.length > 1) {
|
||||
|
||||
for( String id : configs ) {
|
||||
if ( id == null ) {
|
||||
for (String id : configs) {
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
DeploymentConfiguration config = dev.getFlightConfiguration(id);
|
||||
if ( config == null ) {
|
||||
if (dev.getDeploymentConfiguration().isDefault(id)) {
|
||||
continue;
|
||||
}
|
||||
DeploymentConfiguration config = dev.getDeploymentConfiguration().get(id);
|
||||
elements.add("<deploymentconfiguration configid=\"" + id + "\">");
|
||||
elements.addAll( deploymentConfiguration(config, true) );
|
||||
elements.addAll(deploymentConfiguration(config, true));
|
||||
elements.add("</deploymentconfiguration>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> deploymentConfiguration( DeploymentConfiguration config, boolean indent ) {
|
||||
private List<String> deploymentConfiguration(DeploymentConfiguration config, boolean indent) {
|
||||
List<String> elements = new ArrayList<String>(3);
|
||||
elements.add((indent?" ": "") + "<deployevent>" + config.getDeployEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "") + "</deployevent>");
|
||||
elements.add((indent?" ": "") + "<deployaltitude>" + config.getDeployAltitude() + "</deployaltitude>");
|
||||
elements.add((indent?" ": "") + "<deploydelay>" + config.getDeployDelay() + "</deploydelay>");
|
||||
elements.add((indent ? " " : "") + "<deployevent>" + config.getDeployEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "") + "</deployevent>");
|
||||
elements.add((indent ? " " : "") + "<deployaltitude>" + config.getDeployAltitude() + "</deployaltitude>");
|
||||
elements.add((indent ? " " : "") + "<deploydelay>" + config.getDeployDelay() + "</deploydelay>");
|
||||
return elements;
|
||||
|
||||
}
|
||||
|
@ -8,13 +8,13 @@ import java.util.Locale;
|
||||
import net.sf.openrocket.appearance.Appearance;
|
||||
import net.sf.openrocket.appearance.Decal;
|
||||
import net.sf.openrocket.appearance.Decal.EdgeMode;
|
||||
import net.sf.openrocket.file.RocketSaver;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.ThrustCurveMotor;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
|
||||
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
@ -24,6 +24,7 @@ import net.sf.openrocket.util.BugException;
|
||||
import net.sf.openrocket.util.Color;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.LineStyle;
|
||||
import net.sf.openrocket.util.TextUtil;
|
||||
|
||||
public class RocketComponentSaver {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
@ -33,7 +34,7 @@ public class RocketComponentSaver {
|
||||
}
|
||||
|
||||
protected void addParams(net.sf.openrocket.rocketcomponent.RocketComponent c, List<String> elements) {
|
||||
elements.add("<name>" + RocketSaver.escapeXML(c.getName()) + "</name>");
|
||||
elements.add("<name>" + TextUtil.escapeXML(c.getName()) + "</name>");
|
||||
|
||||
ComponentPreset preset = c.getPresetComponent();
|
||||
if (preset != null) {
|
||||
@ -104,7 +105,7 @@ public class RocketComponentSaver {
|
||||
|
||||
// Comment
|
||||
if (c.getComment().length() > 0) {
|
||||
elements.add("<comment>" + RocketSaver.escapeXML(c.getComment()) + "</comment>");
|
||||
elements.add("<comment>" + TextUtil.escapeXML(c.getComment()) + "</comment>");
|
||||
}
|
||||
|
||||
}
|
||||
@ -136,7 +137,7 @@ public class RocketComponentSaver {
|
||||
|
||||
String baseName = trans.getBaseText("material", mat.getName());
|
||||
|
||||
return str + " density=\"" + mat.getDensity() + "\">" + RocketSaver.escapeXML(baseName) + "</" + tag + ">";
|
||||
return str + " density=\"" + mat.getDensity() + "\">" + TextUtil.escapeXML(baseName) + "</" + tag + ">";
|
||||
}
|
||||
|
||||
|
||||
@ -148,11 +149,15 @@ public class RocketComponentSaver {
|
||||
|
||||
elements.add("<motormount>");
|
||||
|
||||
// NOTE: Default config must be BEFORE overridden config for proper backward compatibility later on
|
||||
elements.add(" <ignitionevent>"
|
||||
+ mount.getIgnitionConfiguration().getDefault().getIgnitionEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "")
|
||||
+ "</ignitionevent>");
|
||||
elements.add(" <ignitiondelay>" + mount.getIgnitionConfiguration().getDefault().getIgnitionDelay() + "</ignitiondelay>");
|
||||
elements.add(" <overhang>" + mount.getMotorOverhang() + "</overhang>");
|
||||
|
||||
for (String id : motorConfigIDs) {
|
||||
MotorConfiguration motorConfig = mount.getFlightConfiguration(id);
|
||||
if (motorConfig == null) {
|
||||
continue;
|
||||
}
|
||||
MotorConfiguration motorConfig = mount.getMotorConfiguration().get(id);
|
||||
Motor motor = motorConfig.getMotor();
|
||||
// Nothing is stored if no motor loaded
|
||||
if (motor == null)
|
||||
@ -164,11 +169,11 @@ public class RocketComponentSaver {
|
||||
}
|
||||
if (motor instanceof ThrustCurveMotor) {
|
||||
ThrustCurveMotor m = (ThrustCurveMotor) motor;
|
||||
elements.add(" <manufacturer>" + RocketSaver.escapeXML(m.getManufacturer().getSimpleName()) +
|
||||
elements.add(" <manufacturer>" + TextUtil.escapeXML(m.getManufacturer().getSimpleName()) +
|
||||
"</manufacturer>");
|
||||
elements.add(" <digest>" + m.getDigest() + "</digest>");
|
||||
}
|
||||
elements.add(" <designation>" + RocketSaver.escapeXML(motor.getDesignation()) + "</designation>");
|
||||
elements.add(" <designation>" + TextUtil.escapeXML(motor.getDesignation()) + "</designation>");
|
||||
elements.add(" <diameter>" + motor.getDiameter() + "</diameter>");
|
||||
elements.add(" <length>" + motor.getLength() + "</length>");
|
||||
|
||||
@ -181,27 +186,16 @@ public class RocketComponentSaver {
|
||||
|
||||
elements.add(" </motor>");
|
||||
|
||||
if (motorConfig.getIgnitionEvent() != null || motorConfig.getIgnitionDelay() != null) {
|
||||
if (!mount.getIgnitionConfiguration().isDefault(id)) {
|
||||
IgnitionConfiguration ignition = mount.getIgnitionConfiguration().get(id);
|
||||
elements.add(" <ignitionconfiguration configid=\"" + id + "\">");
|
||||
|
||||
if (motorConfig.getIgnitionEvent() != null) {
|
||||
elements.add(" <ignitionevent>" + motorConfig.getIgnitionEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "") + "</ignitionevent>");
|
||||
}
|
||||
if (motorConfig.getIgnitionDelay() != null) {
|
||||
elements.add(" <ignitiondelay>" + motorConfig.getIgnitionDelay() + "</ignitiondelay>");
|
||||
}
|
||||
|
||||
elements.add(" <ignitionevent>" + ignition.getIgnitionEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "") + "</ignitionevent>");
|
||||
elements.add(" <ignitiondelay>" + ignition.getIgnitionDelay() + "</ignitiondelay>");
|
||||
elements.add(" </ignitionconfiguration>");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
elements.add(" <ignitionevent>"
|
||||
+ mount.getDefaultIgnitionEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "")
|
||||
+ "</ignitionevent>");
|
||||
elements.add(" <ignitiondelay>" + mount.getDefaultIgnitionDelay() + "</ignitiondelay>");
|
||||
elements.add(" <overhang>" + mount.getMotorOverhang() + "</overhang>");
|
||||
|
||||
elements.add("</motormount>");
|
||||
|
||||
return elements;
|
||||
|
@ -29,12 +29,12 @@ public class RocketSaver extends RocketComponentSaver {
|
||||
|
||||
if (rocket.getDesigner().length() > 0) {
|
||||
elements.add("<designer>"
|
||||
+ net.sf.openrocket.file.RocketSaver.escapeXML(rocket.getDesigner())
|
||||
+ net.sf.openrocket.util.TextUtil.escapeXML(rocket.getDesigner())
|
||||
+ "</designer>");
|
||||
}
|
||||
if (rocket.getRevision().length() > 0) {
|
||||
elements.add("<revision>"
|
||||
+ net.sf.openrocket.file.RocketSaver.escapeXML(rocket.getRevision())
|
||||
+ net.sf.openrocket.util.TextUtil.escapeXML(rocket.getRevision())
|
||||
+ "</revision>");
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ public class RocketSaver extends RocketComponentSaver {
|
||||
if (rocket.getFlightConfigurationName(id) == "") {
|
||||
str += "/>";
|
||||
} else {
|
||||
str += "><name>" + net.sf.openrocket.file.RocketSaver.escapeXML(rocket.getFlightConfigurationName(id))
|
||||
str += "><name>" + net.sf.openrocket.util.TextUtil.escapeXML(rocket.getFlightConfigurationName(id))
|
||||
+ "</name></motorconfiguration>";
|
||||
}
|
||||
elements.add(str);
|
||||
|
@ -29,36 +29,37 @@ public class StageSaver extends ComponentAssemblySaver {
|
||||
Stage stage = (Stage) c;
|
||||
|
||||
if (stage.getStageNumber() > 0) {
|
||||
elements.addAll( separationConfig( stage.getDefaultFlightConfiguration(), false));
|
||||
// NOTE: Default config must be BEFORE overridden config for proper backward compatibility later on
|
||||
elements.addAll(separationConfig(stage.getStageSeparationConfiguration().getDefault(), false));
|
||||
|
||||
Rocket rocket = stage.getRocket();
|
||||
// Note - getFlightConfigurationIDs returns at least one element. The first element
|
||||
// is null and means "default".
|
||||
String[] configs = rocket.getFlightConfigurationIDs();
|
||||
if ( configs.length > 1 ) {
|
||||
if (configs.length > 1) {
|
||||
|
||||
for( String id : configs ) {
|
||||
if ( id == null ) {
|
||||
for (String id : configs) {
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
StageSeparationConfiguration config = stage.getFlightConfiguration(id);
|
||||
if ( config == null ) {
|
||||
if (stage.getStageSeparationConfiguration().isDefault(id)) {
|
||||
continue;
|
||||
}
|
||||
StageSeparationConfiguration config = stage.getStageSeparationConfiguration().get(id);
|
||||
elements.add("<separationconfiguration configid=\"" + id + "\">");
|
||||
elements.addAll( separationConfig(config, true) );
|
||||
elements.addAll(separationConfig(config, true));
|
||||
elements.add("</separationconfiguration>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> separationConfig( StageSeparationConfiguration config, boolean indent ) {
|
||||
private List<String> separationConfig(StageSeparationConfiguration config, boolean indent) {
|
||||
List<String> elements = new ArrayList<String>(2);
|
||||
elements.add((indent?" ":"")+ "<separationevent>"
|
||||
elements.add((indent ? " " : "") + "<separationevent>"
|
||||
+ config.getSeparationEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "")
|
||||
+ "</separationevent>");
|
||||
elements.add((indent?" ":"")+ "<separationdelay>" + config.getSeparationDelay() + "</separationdelay>");
|
||||
elements.add((indent ? " " : "") + "<separationdelay>" + config.getSeparationDelay() + "</separationdelay>");
|
||||
return elements;
|
||||
|
||||
}
|
||||
|
@ -51,4 +51,21 @@ public abstract class AbstractElementHandler implements ElementHandler {
|
||||
// No-op
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method for parsing a double value safely.
|
||||
*
|
||||
* @param str the string to parse
|
||||
* @param warnings the warning set
|
||||
* @param warn the warning to add if the value fails to parse
|
||||
* @return the double value, or NaN if an error occurred
|
||||
*/
|
||||
protected double parseDouble(String str, WarningSet warnings, Warning warn) {
|
||||
try {
|
||||
return Double.parseDouble(str);
|
||||
} catch (NumberFormatException e) {
|
||||
warnings.add(warn);
|
||||
return Double.NaN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
package net.sf.openrocket.gui.adaptors;
|
||||
|
||||
import javax.swing.AbstractListModel;
|
||||
import javax.swing.ComboBoxModel;
|
||||
|
||||
|
||||
public class BasicEnumModel<T extends Enum<T>> extends AbstractListModel implements ComboBoxModel {
|
||||
|
||||
private final String nullText;
|
||||
|
||||
private final Enum<T>[] values;
|
||||
private Enum<T> currentValue = null;
|
||||
|
||||
public BasicEnumModel( Class<? extends Enum<T>> clazz ) {
|
||||
this(clazz, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public BasicEnumModel(Class<? extends Enum<T>> clazz, String nullText) {
|
||||
this.values = clazz.getEnumConstants();
|
||||
this.nullText = nullText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedItem(Object anItem) {
|
||||
currentValue = (Enum<T>) anItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSelectedItem() {
|
||||
if (currentValue==null)
|
||||
return nullText;
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
if (values[index] == null)
|
||||
return nullText;
|
||||
return values[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return values.length;
|
||||
}
|
||||
|
||||
}
|
@ -144,7 +144,7 @@ public class MotorConfig extends JPanel {
|
||||
//// plus
|
||||
panel.add(new JLabel(trans.get("MotorCfg.lbl.plus")), "gap indent, skip 1, span, split");
|
||||
|
||||
dm = new DoubleModel(ignitionConfig, "Delay", 0);
|
||||
dm = new DoubleModel(ignitionConfig, "IgnitionDelay", 0);
|
||||
spin = new JSpinner(dm.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin, 3));
|
||||
panel.add(spin, "gap rel rel");
|
||||
|
@ -40,13 +40,14 @@ public class StageConfig extends RocketComponentConfig {
|
||||
// Select separation event
|
||||
panel.add(new StyledLabel(trans.get("separation.lbl.title"), Style.BOLD), "spanx, wrap rel");
|
||||
|
||||
JComboBox combo = new JComboBox(new EnumModel<StageSeparationConfiguration.SeparationEvent>(stage, "DefaultSeparationEvent"));
|
||||
StageSeparationConfiguration config = stage.getStageSeparationConfiguration().getDefault();
|
||||
JComboBox combo = new JComboBox(new EnumModel<StageSeparationConfiguration.SeparationEvent>(config, "SeparationEvent"));
|
||||
panel.add(combo, "");
|
||||
|
||||
// ... and delay
|
||||
panel.add(new JLabel(trans.get("separation.lbl.plus")), "");
|
||||
|
||||
DoubleModel dm = new DoubleModel(stage, "DefaultSeparationDelay", 0);
|
||||
DoubleModel dm = new DoubleModel(config, "SeparationDelay", 0);
|
||||
JSpinner spin = new JSpinner(dm.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
panel.add(spin, "width 45");
|
||||
|
@ -26,7 +26,6 @@ import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.TextUtil;
|
||||
|
||||
public class OperatorSelector extends JDialog {
|
||||
|
||||
@ -40,7 +39,7 @@ public class OperatorSelector extends JDialog {
|
||||
private final OperatorTableModel tableModel;
|
||||
private final ExpressionBuilderDialog parentBuilder;
|
||||
|
||||
public OperatorSelector(Window parent, final ExpressionBuilderDialog parentBuilder){
|
||||
public OperatorSelector(Window parent, final ExpressionBuilderDialog parentBuilder) {
|
||||
|
||||
super(parent, trans.get("CustomOperatorSelector.title"), JDialog.ModalityType.DOCUMENT_MODAL);
|
||||
|
||||
@ -57,19 +56,19 @@ public class OperatorSelector extends JDialog {
|
||||
|
||||
table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
int width = table.getColumnModel().getTotalColumnWidth();
|
||||
table.getColumnModel().getColumn(0).setPreferredWidth( (int) (.1 * width));
|
||||
table.getColumnModel().getColumn(1).setPreferredWidth( (int) (.9 * width));
|
||||
table.getColumnModel().getColumn(0).setPreferredWidth((int) (.1 * width));
|
||||
table.getColumnModel().getColumn(1).setPreferredWidth((int) (.9 * width));
|
||||
table.setAutoCreateRowSorter(true);
|
||||
|
||||
table.addMouseMotionListener(new MouseMotionAdapter(){
|
||||
table.addMouseMotionListener(new MouseMotionAdapter() {
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e){
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
Point p = e.getPoint();
|
||||
int row = table.rowAtPoint(p);
|
||||
int col = table.columnAtPoint(p);
|
||||
if (col == 1 && row > -1){
|
||||
if (col == 1 && row > -1) {
|
||||
String description = String.valueOf(table.getValueAt(row, 1));
|
||||
description = TextUtil.wrap(description, 60);
|
||||
description = wrap(description, 60);
|
||||
table.setToolTipText(description);
|
||||
} else {
|
||||
table.setToolTipText(null);
|
||||
@ -77,29 +76,37 @@ public class OperatorSelector extends JDialog {
|
||||
}
|
||||
});
|
||||
|
||||
table.addMouseListener(new MouseListener(){
|
||||
table.addMouseListener(new MouseListener() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e){
|
||||
if (e.getClickCount() == 2){
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2) {
|
||||
log.debug("Selected operator by double clicking.");
|
||||
selectOperator();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {}
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {}
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {}
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {}
|
||||
} );
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
});
|
||||
|
||||
InputMap inputMap = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||
ActionMap actionMap = table.getActionMap();
|
||||
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
|
||||
inputMap.put(enter, "select");
|
||||
actionMap.put("select", new AbstractAction(){
|
||||
actionMap.put("select", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
log.debug("Selected operator by enter key");
|
||||
@ -111,8 +118,8 @@ public class OperatorSelector extends JDialog {
|
||||
table.setFillsViewportHeight(true);
|
||||
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e){
|
||||
if (table.getSelectedRowCount() == 1){
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (table.getSelectedRowCount() == 1) {
|
||||
insertButton.setEnabled(true);
|
||||
}
|
||||
else {
|
||||
@ -149,10 +156,25 @@ public class OperatorSelector extends JDialog {
|
||||
this.setLocationByPlatform(true);
|
||||
}
|
||||
|
||||
private void selectOperator(){
|
||||
private void selectOperator() {
|
||||
int row = table.getSelectedRow();
|
||||
String str = table.getValueAt(row, 0).toString();
|
||||
parentBuilder.pasteIntoExpression(str);
|
||||
OperatorSelector.this.dispose();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns a word-wrapped version of given input string using HTML syntax, wrapped to len characters.
|
||||
*/
|
||||
private String wrap(String in, int len) {
|
||||
in = in.trim();
|
||||
if (in.length() < len)
|
||||
return in;
|
||||
if (in.substring(0, len).contains("\n"))
|
||||
return in.substring(0, in.indexOf("\n")).trim() + "\n\n" + wrap(in.substring(in.indexOf("\n") + 1), len);
|
||||
int place = Math.max(Math.max(in.lastIndexOf(" ", len), in.lastIndexOf("\t", len)), in.lastIndexOf("-", len));
|
||||
return "<html>" + in.substring(0, place).trim() + "<br>" + wrap(in.substring(place), len);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,147 @@
|
||||
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||
|
||||
import java.awt.Dialog;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JSlider;
|
||||
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.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
public class DeploymentSelectionDialog extends JDialog {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private final DeploymentConfiguration newConfiguration;
|
||||
|
||||
private final JLabel altText;
|
||||
private final JSpinner altSpinner;
|
||||
private final UnitSelector altUnit;
|
||||
private final JSlider altSlider;
|
||||
|
||||
DeploymentSelectionDialog(JDialog parent, final Rocket rocket, final RecoveryDevice component) {
|
||||
super(parent, trans.get("edtmotorconfdlg.title.Selectdeploymentconf"), Dialog.ModalityType.APPLICATION_MODAL);
|
||||
|
||||
final String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
|
||||
newConfiguration = component.getDeploymentConfiguration().get(id).clone();
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
panel.add(new JLabel(trans.get("DeploymentSelectionDialog.opt.title")), "span, wrap rel");
|
||||
final JRadioButton defaultButton = new JRadioButton(trans.get("DeploymentSelectionDialog.opt.default"), true);
|
||||
panel.add(defaultButton, "span, gapleft para, wrap rel");
|
||||
String str = trans.get("DeploymentSelectionDialog.opt.override");
|
||||
str = str.replace("{0}", rocket.getFlightConfigurationNameOrDescription(id));
|
||||
final JRadioButton overrideButton = new JRadioButton(str, false);
|
||||
panel.add(overrideButton, "span, gapleft para, wrap para");
|
||||
|
||||
ButtonGroup buttonGroup = new ButtonGroup();
|
||||
buttonGroup.add(defaultButton);
|
||||
buttonGroup.add(overrideButton);
|
||||
|
||||
|
||||
//// Deployment
|
||||
//// Deploys at:
|
||||
panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Deploysat")), "");
|
||||
|
||||
final JComboBox event = new JComboBox(new EnumModel<DeployEvent>(newConfiguration, "DeployEvent"));
|
||||
panel.add(event, "spanx 3, growx, wrap");
|
||||
|
||||
// ... and delay
|
||||
//// plus
|
||||
panel.add(new JLabel(trans.get("ParachuteCfg.lbl.plusdelay")), "right");
|
||||
|
||||
final DoubleModel delay = new DoubleModel(newConfiguration, "DeployDelay", UnitGroup.UNITS_SHORT_TIME, 0);
|
||||
final JSpinner delaySpinner = new JSpinner(delay.getSpinnerModel());
|
||||
delaySpinner.setEditor(new SpinnerEditor(delaySpinner, 3));
|
||||
panel.add(delaySpinner, "spanx, split");
|
||||
|
||||
//// seconds
|
||||
panel.add(new JLabel(trans.get("ParachuteCfg.lbl.seconds")), "wrap paragraph");
|
||||
|
||||
// Altitude:
|
||||
altText = new JLabel(trans.get("ParachuteCfg.lbl.Altitude"));
|
||||
panel.add(altText);
|
||||
|
||||
final DoubleModel alt = new DoubleModel(newConfiguration, "DeployAltitude", UnitGroup.UNITS_DISTANCE, 0);
|
||||
|
||||
altSpinner = new JSpinner(alt.getSpinnerModel());
|
||||
altSpinner.setEditor(new SpinnerEditor(altSpinner));
|
||||
panel.add(altSpinner, "growx");
|
||||
altUnit = new UnitSelector(alt);
|
||||
panel.add(altUnit, "growx");
|
||||
altSlider = new BasicSlider(alt.getSliderModel(100, 1000));
|
||||
panel.add(altSlider, "w 100lp, wrap");
|
||||
|
||||
event.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
updateState();
|
||||
}
|
||||
});
|
||||
updateState();
|
||||
|
||||
panel.add(new JPanel(), "span, split, growx");
|
||||
|
||||
JButton okButton = new JButton(trans.get("button.ok"));
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (defaultButton.isSelected()) {
|
||||
component.getDeploymentConfiguration().setDefault(newConfiguration);
|
||||
} else {
|
||||
component.getDeploymentConfiguration().set(id, newConfiguration);
|
||||
}
|
||||
DeploymentSelectionDialog.this.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(okButton, "sizegroup btn");
|
||||
|
||||
JButton cancel = new JButton(trans.get("button.cancel"));
|
||||
cancel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
DeploymentSelectionDialog.this.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(cancel, "sizegroup btn");
|
||||
|
||||
this.setContentPane(panel);
|
||||
GUIUtil.setDisposableDialogOptions(this, okButton);
|
||||
}
|
||||
|
||||
|
||||
private void updateState() {
|
||||
boolean enabled = (newConfiguration.getDeployEvent() == DeployEvent.ALTITUDE);
|
||||
altText.setEnabled(enabled);
|
||||
altSpinner.setEnabled(enabled);
|
||||
altUnit.setEnabled(enabled);
|
||||
altSlider.setEnabled(enabled);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -16,6 +16,7 @@ import javax.swing.JTabbedPane;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.adaptors.FlightConfigurationModel;
|
||||
import net.sf.openrocket.gui.main.BasicFrame;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
@ -23,9 +24,13 @@ import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketvisitors.CopyFlightConfigurationVisitor;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
/**
|
||||
* Dialog for configuring all flight-configuration specific properties.
|
||||
* Content of individual tabs are in separate classes.
|
||||
*/
|
||||
public class FlightConfigurationDialog extends JDialog {
|
||||
|
||||
static final Translator trans = Application.getTranslator();
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private final Rocket rocket;
|
||||
|
||||
@ -58,7 +63,7 @@ public class FlightConfigurationDialog extends JDialog {
|
||||
JLabel label = new JLabel("Selected Configuration:");
|
||||
panel.add(label);
|
||||
|
||||
flightConfigurationModel = new FlightConfigurationModel(this, rocket.getDefaultConfiguration());
|
||||
flightConfigurationModel = new FlightConfigurationModel(rocket.getDefaultConfiguration());
|
||||
JComboBox configSelector = new JComboBox(flightConfigurationModel);
|
||||
|
||||
panel.add(configSelector, "gapright para");
|
||||
@ -78,7 +83,7 @@ public class FlightConfigurationDialog extends JDialog {
|
||||
renameConfButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new RenameConfigDialog(rocket, FlightConfigurationDialog.this).setVisible(true);
|
||||
new RenameConfigDialog(FlightConfigurationDialog.this, rocket).setVisible(true);
|
||||
}
|
||||
});
|
||||
panel.add(renameConfButton);
|
||||
@ -111,7 +116,6 @@ public class FlightConfigurationDialog extends JDialog {
|
||||
//// Motor tabs
|
||||
motorConfigurationPanel = new MotorConfigurationPanel(this, rocket);
|
||||
tabs.add(trans.get("edtmotorconfdlg.lbl.Motortab"), motorConfigurationPanel);
|
||||
|
||||
//// Recovery tab
|
||||
recoveryConfigurationPanel = new RecoveryConfigurationPanel(this, rocket);
|
||||
tabs.add(trans.get("edtmotorconfdlg.lbl.Recoverytab"), recoveryConfigurationPanel);
|
||||
@ -122,6 +126,7 @@ public class FlightConfigurationDialog extends JDialog {
|
||||
tabs.add(trans.get("edtmotorconfdlg.lbl.Stagetab"), separationConfigurationPanel);
|
||||
}
|
||||
|
||||
|
||||
//// Close button
|
||||
JButton close = new JButton(trans.get("dlg.but.close"));
|
||||
close.addActionListener(new ActionListener() {
|
||||
@ -168,7 +173,6 @@ public class FlightConfigurationDialog extends JDialog {
|
||||
currentID = rocket.newFlightConfigurationID();
|
||||
rocket.getDefaultConfiguration().setFlightConfigurationID(currentID);
|
||||
motorConfigurationPanel.fireTableDataChanged();
|
||||
flightConfigurationModel.fireContentsUpdated();
|
||||
recoveryConfigurationPanel.fireTableDataChanged();
|
||||
separationConfigurationPanel.fireTableDataChanged();
|
||||
updateButtonState();
|
||||
@ -185,7 +189,6 @@ public class FlightConfigurationDialog extends JDialog {
|
||||
// Copy the name.
|
||||
this.changeConfigurationName(oldName);
|
||||
motorConfigurationPanel.fireTableDataChanged();
|
||||
flightConfigurationModel.fireContentsUpdated();
|
||||
recoveryConfigurationPanel.fireTableDataChanged();
|
||||
separationConfigurationPanel.fireTableDataChanged();
|
||||
updateButtonState();
|
||||
@ -193,7 +196,6 @@ public class FlightConfigurationDialog extends JDialog {
|
||||
|
||||
public void changeConfigurationName(String newName) {
|
||||
rocket.setFlightConfigurationName(currentID, newName);
|
||||
flightConfigurationModel.fireContentsUpdated();
|
||||
}
|
||||
|
||||
public void removeConfiguration() {
|
||||
@ -202,7 +204,6 @@ public class FlightConfigurationDialog extends JDialog {
|
||||
rocket.removeFlightConfigurationID(currentID);
|
||||
rocket.getDefaultConfiguration().setFlightConfigurationID(null);
|
||||
motorConfigurationPanel.fireTableDataChanged();
|
||||
flightConfigurationModel.fireContentsUpdated();
|
||||
recoveryConfigurationPanel.fireTableDataChanged();
|
||||
separationConfigurationPanel.fireTableDataChanged();
|
||||
updateButtonState();
|
||||
@ -212,7 +213,6 @@ public class FlightConfigurationDialog extends JDialog {
|
||||
* Call this from other panels when a change might cause the names of the configurations to change.
|
||||
*/
|
||||
public void fireContentsUpdated() {
|
||||
flightConfigurationModel.fireContentsUpdated();
|
||||
}
|
||||
|
||||
private void updateButtonState() {
|
||||
|
@ -1,98 +0,0 @@
|
||||
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
|
||||
public class FlightConfigurationModel extends DefaultComboBoxModel {
|
||||
|
||||
private final Configuration config;
|
||||
private final Rocket rocket;
|
||||
|
||||
private Map<String, ID> map = new HashMap<String, ID>();
|
||||
|
||||
private final FlightConfigurationDialog flightConfigurationDialog;
|
||||
|
||||
public FlightConfigurationModel(FlightConfigurationDialog flightConfigurationDialog, Configuration config) {
|
||||
this.flightConfigurationDialog = flightConfigurationDialog;
|
||||
this.config = config;
|
||||
this.rocket = config.getRocket();
|
||||
}
|
||||
|
||||
void fireContentsUpdated() {
|
||||
fireContentsChanged(this, 0, rocket.getFlightConfigurationIDs().length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
String[] ids = rocket.getFlightConfigurationIDs();
|
||||
if (index < 0 || index >= ids.length)
|
||||
return null;
|
||||
|
||||
return get(ids[index]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return rocket.getFlightConfigurationIDs().length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSelectedItem() {
|
||||
return get(config.getFlightConfigurationID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedItem(Object item) {
|
||||
if (item == null) {
|
||||
// Clear selection - huh?
|
||||
return;
|
||||
}
|
||||
if (!(item instanceof ID)) {
|
||||
throw new IllegalArgumentException("MotorConfigurationModel item="+item);
|
||||
}
|
||||
|
||||
ID idObject = (ID) item;
|
||||
flightConfigurationDialog.selectConfiguration(idObject.getID());
|
||||
}
|
||||
|
||||
/*
|
||||
* The ID class is an adapter, that contains the actual configuration ID,
|
||||
* but gives the configuration description as its String representation.
|
||||
* The get(id) method retrieves ID objects and caches them for reuse.
|
||||
*/
|
||||
|
||||
private ID get(String id) {
|
||||
ID idObject = map.get(id);
|
||||
if (idObject != null)
|
||||
return idObject;
|
||||
|
||||
idObject = new ID(id);
|
||||
map.put(id, idObject);
|
||||
return idObject;
|
||||
}
|
||||
|
||||
|
||||
private class ID {
|
||||
private final String id;
|
||||
|
||||
public ID(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return rocket.getFlightConfigurationNameOrDescription(id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,107 @@
|
||||
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||
|
||||
import java.awt.Dialog;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
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.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration.IgnitionEvent;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
public class IgnitionSelectionDialog extends JDialog {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
|
||||
private IgnitionConfiguration newConfiguration;
|
||||
|
||||
IgnitionSelectionDialog(JDialog parent, final Rocket rocket, final MotorMount component) {
|
||||
super(parent, trans.get("edtmotorconfdlg.title.Selectignitionconf"), Dialog.ModalityType.APPLICATION_MODAL);
|
||||
final String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
|
||||
newConfiguration = component.getIgnitionConfiguration().get(id).clone();
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
panel.add(new JLabel(trans.get("IgnitionSelectionDialog.opt.title")), "span, wrap rel");
|
||||
final JRadioButton defaultButton = new JRadioButton(trans.get("IgnitionSelectionDialog.opt.default"), true);
|
||||
panel.add(defaultButton, "span, gapleft para, wrap rel");
|
||||
String str = trans.get("IgnitionSelectionDialog.opt.override");
|
||||
str = str.replace("{0}", rocket.getFlightConfigurationNameOrDescription(id));
|
||||
final JRadioButton overrideButton = new JRadioButton(str, false);
|
||||
panel.add(overrideButton, "span, gapleft para, wrap para");
|
||||
|
||||
ButtonGroup buttonGroup = new ButtonGroup();
|
||||
buttonGroup.add(defaultButton);
|
||||
buttonGroup.add(overrideButton);
|
||||
|
||||
// Select ignition event
|
||||
//// Ignition at:
|
||||
panel.add(new JLabel(trans.get("MotorCfg.lbl.Ignitionat")), "");
|
||||
|
||||
final JComboBox event = new JComboBox(new EnumModel<IgnitionEvent>(newConfiguration, "IgnitionEvent"));
|
||||
panel.add(event, "growx, wrap");
|
||||
|
||||
// ... and delay
|
||||
//// plus
|
||||
panel.add(new JLabel(trans.get("MotorCfg.lbl.plus")), "gap indent, skip 1, span, split");
|
||||
|
||||
DoubleModel delay = new DoubleModel(newConfiguration, "IgnitionDelay", UnitGroup.UNITS_SHORT_TIME, 0);
|
||||
JSpinner spin = new JSpinner(delay.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin, 3));
|
||||
panel.add(spin, "gap rel rel");
|
||||
|
||||
//// seconds
|
||||
panel.add(new JLabel(trans.get("MotorCfg.lbl.seconds")), "wrap unrel");
|
||||
|
||||
|
||||
panel.add(new JPanel(), "span, split, growx");
|
||||
|
||||
JButton okButton = new JButton(trans.get("button.ok"));
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (defaultButton.isSelected()) {
|
||||
component.getIgnitionConfiguration().setDefault(newConfiguration);
|
||||
} else {
|
||||
component.getIgnitionConfiguration().set(id, newConfiguration);
|
||||
}
|
||||
IgnitionSelectionDialog.this.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(okButton, "sizegroup btn");
|
||||
|
||||
JButton cancel = new JButton(trans.get("button.cancel"));
|
||||
cancel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
IgnitionSelectionDialog.this.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(cancel, "sizegroup btn");
|
||||
|
||||
this.setContentPane(panel);
|
||||
|
||||
GUIUtil.setDisposableDialogOptions(this, okButton);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.rocketcomponent.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
@ -87,6 +88,7 @@ public class MotorConfigurationPanel extends JPanel {
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
updateButtonState();
|
||||
if (e.getClickCount() == 2) {
|
||||
// FIXME: Double-click on ignition column should select ignition
|
||||
// Double-click edits motor
|
||||
selectMotor();
|
||||
}
|
||||
@ -177,23 +179,27 @@ public class MotorConfigurationPanel extends JPanel {
|
||||
}
|
||||
|
||||
private void selectMotor() {
|
||||
String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
MotorMount currentMount = getCurrentMount();
|
||||
if (currentID == null || currentMount == null)
|
||||
String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
MotorMount mount = getCurrentMount();
|
||||
if (id == null || mount == null)
|
||||
return;
|
||||
|
||||
MotorConfiguration config = mount.getMotorConfiguration().get(id);
|
||||
|
||||
MotorChooserDialog dialog = new MotorChooserDialog(
|
||||
currentMount.getMotor(currentID),
|
||||
currentMount.getMotorDelay(currentID),
|
||||
currentMount.getMotorMountDiameter(),
|
||||
config.getMotor(),
|
||||
config.getEjectionDelay(),
|
||||
mount.getMotorMountDiameter(),
|
||||
flightConfigurationDialog);
|
||||
dialog.setVisible(true);
|
||||
Motor m = dialog.getSelectedMotor();
|
||||
double d = dialog.getSelectedDelay();
|
||||
|
||||
if (m != null) {
|
||||
currentMount.setMotor(currentID, m);
|
||||
currentMount.setMotorDelay(currentID, d);
|
||||
config = new MotorConfiguration();
|
||||
config.setMotor(m);
|
||||
config.setEjectionDelay(d);
|
||||
mount.getMotorConfiguration().set(id, config);
|
||||
}
|
||||
|
||||
flightConfigurationDialog.fireContentsUpdated();
|
||||
@ -202,12 +208,12 @@ public class MotorConfigurationPanel extends JPanel {
|
||||
}
|
||||
|
||||
private void removeMotor() {
|
||||
String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
MotorMount currentMount = getCurrentMount();
|
||||
if (currentID == null || currentMount == null)
|
||||
String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
MotorMount mount = getCurrentMount();
|
||||
if (id == null || mount == null)
|
||||
return;
|
||||
|
||||
currentMount.setMotor(currentID, null);
|
||||
mount.getMotorConfiguration().resetDefault(id);
|
||||
|
||||
flightConfigurationDialog.fireContentsUpdated();
|
||||
configurationTableModel.fireTableDataChanged();
|
||||
@ -220,7 +226,7 @@ public class MotorConfigurationPanel extends JPanel {
|
||||
if (currentID == null || currentMount == null)
|
||||
return;
|
||||
|
||||
SelectIgnitionConfigDialog dialog = new SelectIgnitionConfigDialog(
|
||||
IgnitionSelectionDialog dialog = new IgnitionSelectionDialog(
|
||||
this.flightConfigurationDialog,
|
||||
rocket,
|
||||
currentMount);
|
||||
|
@ -19,12 +19,12 @@ import net.sf.openrocket.util.Coordinate;
|
||||
*/
|
||||
class MotorConfigurationTableModel extends AbstractTableModel {
|
||||
|
||||
private Translator trans = Application.getTranslator();
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private final static String NONE = FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.None");
|
||||
private final static String MOTOR_MOUNT = FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Mountheader");
|
||||
private final static String MOTOR = FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Motorheader");
|
||||
private final static String IGNITION = FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Ignitionheader");
|
||||
private static final String NONE = trans.get("edtmotorconfdlg.tbl.None");
|
||||
private static final String MOTOR_MOUNT = trans.get("edtmotorconfdlg.tbl.Mountheader");
|
||||
private static final String MOTOR = trans.get("edtmotorconfdlg.tbl.Motorheader");
|
||||
private static final String IGNITION = trans.get("edtmotorconfdlg.tbl.Ignitionheader");
|
||||
|
||||
private final Rocket rocket;
|
||||
|
||||
@ -63,13 +63,14 @@ class MotorConfigurationTableModel extends AbstractTableModel {
|
||||
}
|
||||
case 1: {
|
||||
MotorMount mount = findMount(row);
|
||||
String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
Motor motor = mount.getMotor(currentID);
|
||||
String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
MotorConfiguration config = mount.getMotorConfiguration().get(id);
|
||||
Motor motor = config.getMotor();
|
||||
|
||||
if (motor == null)
|
||||
return NONE;
|
||||
|
||||
String str = motor.getDesignation(mount.getMotorDelay(currentID));
|
||||
String str = motor.getDesignation(config.getEjectionDelay());
|
||||
int count = getMountMultiplicity(mount);
|
||||
if (count > 1) {
|
||||
str = "" + count + Chars.TIMES + " " + str;
|
||||
@ -124,26 +125,16 @@ class MotorConfigurationTableModel extends AbstractTableModel {
|
||||
|
||||
|
||||
private String getIgnitionEventString(int row) {
|
||||
String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
MotorMount mount = findMount(row);
|
||||
MotorConfiguration motorConfig = mount.getFlightConfiguration(currentID);
|
||||
if (motorConfig == null) {
|
||||
return NONE;
|
||||
}
|
||||
IgnitionConfiguration ignitionConfig = mount.getIgnitionConfiguration().get(id);
|
||||
|
||||
IgnitionConfiguration.IgnitionEvent ignition = motorConfig.getIgnitionEvent();
|
||||
Double ignitionDelay = motorConfig.getIgnitionDelay();
|
||||
boolean isDefault = (ignition == null);
|
||||
IgnitionConfiguration.IgnitionEvent ignitionEvent = ignitionConfig.getIgnitionEvent();
|
||||
Double ignitionDelay = ignitionConfig.getIgnitionDelay();
|
||||
boolean isDefault = mount.getIgnitionConfiguration().isDefault(id);
|
||||
|
||||
if (ignition == null) {
|
||||
ignition = mount.getDefaultIgnitionEvent();
|
||||
}
|
||||
if (ignitionDelay == null) {
|
||||
ignitionDelay = mount.getDefaultIgnitionDelay();
|
||||
}
|
||||
|
||||
String str = trans.get("MotorMount.IgnitionEvent.short." + ignition.name());
|
||||
if (ignitionDelay > 0) {
|
||||
String str = trans.get("MotorMount.IgnitionEvent.short." + ignitionEvent.name());
|
||||
if (ignitionDelay > 0.001) {
|
||||
str = str + " + " + UnitGroup.UNITS_SHORT_TIME.toStringUnit(ignitionDelay);
|
||||
}
|
||||
if (isDefault) {
|
||||
|
@ -15,60 +15,57 @@ import javax.swing.ListSelectionModel;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
public class RecoveryConfigurationPanel extends JPanel {
|
||||
|
||||
private Translator trans = Application.getTranslator();
|
||||
|
||||
|
||||
private final FlightConfigurationDialog flightConfigurationDialog;
|
||||
private final Rocket rocket;
|
||||
|
||||
private final RecoveryTableModel recoveryTableModel;
|
||||
private final JTable recoveryTable;
|
||||
private final JButton selectDeploymentButton;
|
||||
private final JButton resetDeploymentButton;
|
||||
|
||||
private RecoveryDevice selectedComponent;
|
||||
|
||||
RecoveryConfigurationPanel( FlightConfigurationDialog flightConfigurationDialog, Rocket rocket ) {
|
||||
super( new MigLayout("fill") );
|
||||
RecoveryConfigurationPanel(FlightConfigurationDialog flightConfigurationDialog, Rocket rocket) {
|
||||
super(new MigLayout("fill"));
|
||||
this.flightConfigurationDialog = flightConfigurationDialog;
|
||||
this.rocket = rocket;
|
||||
|
||||
//// Recovery selection
|
||||
recoveryTableModel = new RecoveryTableModel();
|
||||
JTable table = new JTable( recoveryTableModel );
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
table.setRowSelectionAllowed(true);
|
||||
table.addMouseListener(new MouseAdapter() {
|
||||
recoveryTable = new JTable(recoveryTableModel);
|
||||
recoveryTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
recoveryTable.setRowSelectionAllowed(true);
|
||||
recoveryTable.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
JTable table = (JTable) e.getComponent();
|
||||
int row = table.getSelectedRow();
|
||||
|
||||
if ( row >= 0 ) {
|
||||
selectedComponent = findRecoveryDevice(row);
|
||||
} else {
|
||||
selectedComponent = null;
|
||||
}
|
||||
|
||||
if (e.getClickCount() == 1) {
|
||||
// Single click updates selection
|
||||
updateButtonState();
|
||||
} else if (e.getClickCount() == 2) {
|
||||
|
||||
if (e.getClickCount() == 2) {
|
||||
// Double-click edits
|
||||
selectDeployment();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
JScrollPane scroll = new JScrollPane(table);
|
||||
JScrollPane scroll = new JScrollPane(recoveryTable);
|
||||
this.add(scroll, "span, grow, wrap");
|
||||
|
||||
//// Select deployment
|
||||
selectDeploymentButton = new JButton(FlightConfigurationDialog.trans.get("edtmotorconfdlg.but.Selectdeployment"));
|
||||
selectDeploymentButton = new JButton(trans.get("edtmotorconfdlg.but.Selectdeployment"));
|
||||
selectDeploymentButton.setEnabled(false);
|
||||
selectDeploymentButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@ -79,7 +76,7 @@ public class RecoveryConfigurationPanel extends JPanel {
|
||||
this.add(selectDeploymentButton, "skip, split, sizegroup button");
|
||||
|
||||
//// Reset deployment
|
||||
resetDeploymentButton = new JButton(FlightConfigurationDialog.trans.get("edtmotorconfdlg.but.Resetdeployment"));
|
||||
resetDeploymentButton = new JButton(trans.get("edtmotorconfdlg.but.Resetdeployment"));
|
||||
resetDeploymentButton.setEnabled(false);
|
||||
resetDeploymentButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@ -87,43 +84,52 @@ public class RecoveryConfigurationPanel extends JPanel {
|
||||
resetDeployment();
|
||||
}
|
||||
});
|
||||
this.add(resetDeploymentButton,"sizegroup button, wrap");
|
||||
|
||||
this.add(resetDeploymentButton, "sizegroup button, wrap");
|
||||
}
|
||||
|
||||
public void fireTableDataChanged() {
|
||||
selectedComponent = null;
|
||||
recoveryTableModel.fireTableDataChanged();
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
private void selectDeployment() {
|
||||
JDialog d = new SelectDeploymentConfigDialog( flightConfigurationDialog, rocket, selectedComponent );
|
||||
RecoveryDevice c = getSelectedComponent();
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
JDialog d = new DeploymentSelectionDialog(flightConfigurationDialog, rocket, c);
|
||||
d.setVisible(true);
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
private void resetDeployment() {
|
||||
selectedComponent.setFlightConfiguration(rocket.getDefaultConfiguration().getFlightConfigurationID(), null);
|
||||
RecoveryDevice c = getSelectedComponent();
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
c.getDeploymentConfiguration().resetDefault(id);
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
public void updateButtonState() {
|
||||
boolean componentSelected = selectedComponent != null;
|
||||
boolean isDefaulted = true;
|
||||
if ( componentSelected ) {
|
||||
isDefaulted = selectedComponent.getFlightConfiguration(rocket.getDefaultConfiguration().getFlightConfigurationID()) == null;
|
||||
}
|
||||
boolean componentSelected = getSelectedComponent() != null;
|
||||
selectDeploymentButton.setEnabled(componentSelected);
|
||||
resetDeploymentButton.setEnabled(componentSelected & ! isDefaulted);
|
||||
resetDeploymentButton.setEnabled(componentSelected);
|
||||
}
|
||||
|
||||
private RecoveryDevice findRecoveryDevice( int count ) {
|
||||
|
||||
private RecoveryDevice getSelectedComponent() {
|
||||
int row = recoveryTable.getSelectedRow();
|
||||
return findRecoveryDevice(row);
|
||||
}
|
||||
|
||||
private RecoveryDevice findRecoveryDevice(int count) {
|
||||
RecoveryDevice d = null;
|
||||
Iterator<RocketComponent> it = rocket.iterator();
|
||||
while( it.hasNext() && count >= 0 ) {
|
||||
while (it.hasNext() && count >= 0) {
|
||||
RocketComponent c = it.next();
|
||||
if ( c instanceof RecoveryDevice ) {
|
||||
if (c instanceof RecoveryDevice) {
|
||||
d = (RecoveryDevice) c;
|
||||
count--;
|
||||
}
|
||||
@ -131,16 +137,18 @@ public class RecoveryConfigurationPanel extends JPanel {
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class RecoveryTableModel extends AbstractTableModel {
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
int count = 0;
|
||||
Iterator<RocketComponent> it = rocket.iterator();
|
||||
while( it.hasNext() ) {
|
||||
while (it.hasNext()) {
|
||||
RocketComponent c = it.next();
|
||||
if ( c instanceof RecoveryDevice ) {
|
||||
count ++;
|
||||
if (c instanceof RecoveryDevice) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
@ -153,29 +161,45 @@ public class RecoveryConfigurationPanel extends JPanel {
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
RecoveryDevice d = RecoveryConfigurationPanel.this.findRecoveryDevice(rowIndex);
|
||||
switch ( columnIndex ) {
|
||||
RecoveryDevice d = findRecoveryDevice(rowIndex);
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return d.getName();
|
||||
case 1:
|
||||
DeploymentConfiguration deployConfig = d.getFlightConfiguration(rocket.getDefaultConfiguration().getFlightConfigurationID());
|
||||
if ( deployConfig == null ) {
|
||||
return "[" + d.getDefaultFlightConfiguration().toString() + "]";
|
||||
} else {
|
||||
return deployConfig.toString();
|
||||
String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
DeploymentConfiguration config = d.getDeploymentConfiguration().get(id);
|
||||
boolean isDefault = d.getDeploymentConfiguration().isDefault(id);
|
||||
|
||||
String str;
|
||||
|
||||
str = trans.get("RecoveryDevice.DeployEvent.short." + config.getDeployEvent().name());
|
||||
if (config.getDeployEvent() == DeployEvent.ALTITUDE) {
|
||||
str += " " + UnitGroup.UNITS_DISTANCE.toStringUnit(config.getDeployAltitude());
|
||||
}
|
||||
if (config.getDeployDelay() > 0.001) {
|
||||
str += " + " + UnitGroup.UNITS_SHORT_TIME.toStringUnit(config.getDeployDelay());
|
||||
}
|
||||
|
||||
|
||||
if (isDefault) {
|
||||
String def = trans.get("table.deployment.default");
|
||||
str = def.replace("{0}", str);
|
||||
}
|
||||
return str;
|
||||
|
||||
default:
|
||||
throw new IndexOutOfBoundsException("columnIndex=" + columnIndex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
switch ( column ) {
|
||||
switch (column) {
|
||||
case 0:
|
||||
return FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Recoveryheader");
|
||||
return trans.get("edtmotorconfdlg.tbl.Recoveryheader");
|
||||
case 1:
|
||||
return FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Deploymentheader");
|
||||
return trans.get("edtmotorconfdlg.tbl.Deploymentheader");
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
@ -10,22 +10,26 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
public class RenameConfigDialog extends JDialog {
|
||||
|
||||
RenameConfigDialog( final Rocket rocket, final FlightConfigurationDialog parent ) {
|
||||
super(parent, FlightConfigurationDialog.trans.get("edtmotorconfdlg.title.Renameconf"),Dialog.ModalityType.APPLICATION_MODAL);
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
RenameConfigDialog(final FlightConfigurationDialog parent, final Rocket rocket) {
|
||||
super(parent, trans.get("edtmotorconfdlg.title.Renameconf"), Dialog.ModalityType.APPLICATION_MODAL);
|
||||
final Configuration config = rocket.getDefaultConfiguration();
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
final JTextArea textbox = new JTextArea( config.getFlightConfigurationDescription() );
|
||||
final JTextArea textbox = new JTextArea(config.getFlightConfigurationDescription());
|
||||
panel.add(textbox, "span, w 200lp, wrap");
|
||||
|
||||
JButton okButton = new JButton("Ok");
|
||||
okButton.addActionListener( new ActionListener() {
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@ -35,10 +39,10 @@ public class RenameConfigDialog extends JDialog {
|
||||
|
||||
});
|
||||
|
||||
panel.add( okButton );
|
||||
panel.add(okButton);
|
||||
|
||||
JButton defaultButton = new JButton("Reset to default");
|
||||
defaultButton.addActionListener( new ActionListener() {
|
||||
defaultButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@ -48,10 +52,10 @@ public class RenameConfigDialog extends JDialog {
|
||||
|
||||
});
|
||||
|
||||
panel.add( defaultButton );
|
||||
panel.add(defaultButton);
|
||||
|
||||
JButton cancel = new JButton("Cancel");
|
||||
cancel.addActionListener( new ActionListener() {
|
||||
cancel.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@ -60,7 +64,7 @@ public class RenameConfigDialog extends JDialog {
|
||||
|
||||
});
|
||||
|
||||
panel.add( cancel );
|
||||
panel.add(cancel);
|
||||
|
||||
this.setContentPane(panel);
|
||||
this.validate();
|
||||
|
@ -1,145 +0,0 @@
|
||||
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||
|
||||
import java.awt.Dialog;
|
||||
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 javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.adaptors.BasicEnumModel;
|
||||
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.rocketcomponent.DeploymentConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
public class SelectDeploymentConfigDialog extends JDialog {
|
||||
|
||||
DeploymentConfiguration newConfiguration;
|
||||
|
||||
|
||||
SelectDeploymentConfigDialog( JDialog parent, final Rocket rocket, final RecoveryDevice component ) {
|
||||
super(parent, FlightConfigurationDialog.trans.get("edtmotorconfdlg.title.Selectdeploymentconf"),Dialog.ModalityType.APPLICATION_MODAL);
|
||||
|
||||
final String configId = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
|
||||
newConfiguration = component.getFlightConfiguration(configId);
|
||||
if ( newConfiguration == null ) {
|
||||
newConfiguration = component.getDefaultFlightConfiguration().clone();
|
||||
} else {
|
||||
// Clone the existing so cancel works. When the user selects OK, this configuration
|
||||
// is put back in there.
|
||||
newConfiguration = newConfiguration.clone();
|
||||
}
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
//// Deployment
|
||||
//// Deploys at:
|
||||
panel.add(new JLabel(FlightConfigurationDialog.trans.get("ParachuteCfg.lbl.Deploysat")), "");
|
||||
|
||||
final JComboBox event = new JComboBox(new BasicEnumModel<DeployEvent>(DeployEvent.class));
|
||||
event.setSelectedItem( newConfiguration.getDeployEvent() );
|
||||
panel.add(event, "spanx 3, growx, wrap");
|
||||
|
||||
// ... and delay
|
||||
//// plus
|
||||
panel.add(new JLabel(FlightConfigurationDialog.trans.get("ParachuteCfg.lbl.plusdelay")), "right");
|
||||
|
||||
final DoubleModel delay = new DoubleModel(newConfiguration.getDeployDelay(), UnitGroup.UNITS_NONE, 0);
|
||||
final JSpinner delaySpinner = new JSpinner( delay.getSpinnerModel() );
|
||||
delaySpinner.setEditor(new SpinnerEditor(delaySpinner,3));
|
||||
panel.add(delaySpinner, "spanx, split");
|
||||
|
||||
//// seconds
|
||||
panel.add(new JLabel(FlightConfigurationDialog.trans.get("ParachuteCfg.lbl.seconds")), "wrap paragraph");
|
||||
|
||||
// Altitude:
|
||||
JLabel label = new JLabel(FlightConfigurationDialog.trans.get("ParachuteCfg.lbl.Altitude"));
|
||||
panel.add(label);
|
||||
|
||||
final DoubleModel alt = new DoubleModel(newConfiguration.getDeployAltitude(), UnitGroup.UNITS_DISTANCE, 0);
|
||||
|
||||
final JSpinner altSpinner = new JSpinner(alt.getSpinnerModel());
|
||||
altSpinner.setEditor(new SpinnerEditor(altSpinner));
|
||||
panel.add(altSpinner, "growx");
|
||||
UnitSelector unit = new UnitSelector(alt);
|
||||
panel.add(unit, "growx");
|
||||
BasicSlider slider = new BasicSlider(alt.getSliderModel(100, 1000));
|
||||
panel.add(slider, "w 100lp, wrap");
|
||||
|
||||
event.addActionListener( new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if ( event.getSelectedItem() == DeployEvent.ALTITUDE ) {
|
||||
altSpinner.setEnabled(true);
|
||||
} else {
|
||||
altSpinner.setEnabled(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Set the value of the combo box at the end to take advantage of the action listener above.
|
||||
event.setSelectedItem( newConfiguration.getDeployEvent() );
|
||||
|
||||
JButton okButton = new JButton(FlightConfigurationDialog.trans.get("button.ok"));
|
||||
okButton.addActionListener( new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
//// extract deployment type;
|
||||
DeployEvent deployEvent = (DeployEvent) event.getSelectedItem();
|
||||
newConfiguration.setDeployEvent(deployEvent);
|
||||
|
||||
//// extract deployment time;
|
||||
double deployDelay = delay.getValue();
|
||||
newConfiguration.setDeployDelay(deployDelay);
|
||||
|
||||
//// extract altitude;
|
||||
double deployAltitude = alt.getValue();
|
||||
newConfiguration.setDeployAltitude(deployAltitude);
|
||||
|
||||
component.setFlightConfiguration(configId, newConfiguration);
|
||||
|
||||
SelectDeploymentConfigDialog.this.setVisible(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
panel.add( okButton );
|
||||
|
||||
JButton cancel = new JButton(FlightConfigurationDialog.trans.get("button.cancel"));
|
||||
cancel.addActionListener( new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SelectDeploymentConfigDialog.this.setVisible(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
panel.add( cancel );
|
||||
|
||||
this.setContentPane(panel);
|
||||
this.validate();
|
||||
this.pack();
|
||||
this.setLocationByPlatform(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||
|
||||
import java.awt.Dialog;
|
||||
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 javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.adaptors.BasicEnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration.IgnitionEvent;
|
||||
import net.sf.openrocket.rocketcomponent.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
public class SelectIgnitionConfigDialog extends JDialog {
|
||||
|
||||
MotorConfiguration newConfiguration;
|
||||
|
||||
SelectIgnitionConfigDialog(JDialog parent, final Rocket rocket, final MotorMount component) {
|
||||
super(parent, FlightConfigurationDialog.trans.get("edtmotorconfdlg.title.Selectignitionconf"), Dialog.ModalityType.APPLICATION_MODAL);
|
||||
final String configId = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
|
||||
newConfiguration = component.getFlightConfiguration(configId);
|
||||
if (newConfiguration == null) {
|
||||
newConfiguration = component.getDefaultFlightConfiguration().clone();
|
||||
} else {
|
||||
// Clone the existing so cancel works. When the user selects OK, this configuration
|
||||
// is put back in there.
|
||||
newConfiguration = newConfiguration.clone();
|
||||
}
|
||||
// MotorConfiguration is a little wierd. It is possible for the MotorConfiguration
|
||||
// to be non-null (for example, a motor is selected) but the ignition spec is null
|
||||
// (ignition is not overridden). In order to accomodate this, we need to test
|
||||
// for IgnitionEvent and copy from the default config.
|
||||
if (newConfiguration.getIgnitionEvent() == null) {
|
||||
MotorConfiguration oldConfig = component.getDefaultFlightConfiguration();
|
||||
newConfiguration.setIgnitionDelay(oldConfig.getIgnitionDelay());
|
||||
newConfiguration.setIgnitionEvent(oldConfig.getIgnitionEvent());
|
||||
}
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
// Select ignition event
|
||||
//// Ignition at:
|
||||
panel.add(new JLabel(FlightConfigurationDialog.trans.get("MotorCfg.lbl.Ignitionat")), "");
|
||||
|
||||
final JComboBox event = new JComboBox(new BasicEnumModel<IgnitionConfiguration.IgnitionEvent>(IgnitionConfiguration.IgnitionEvent.class));
|
||||
event.setSelectedItem(newConfiguration.getIgnitionEvent());
|
||||
panel.add(event, "growx, wrap");
|
||||
|
||||
// ... and delay
|
||||
//// plus
|
||||
panel.add(new JLabel(FlightConfigurationDialog.trans.get("MotorCfg.lbl.plus")), "gap indent, skip 1, span, split");
|
||||
|
||||
Double delayValue = newConfiguration.getIgnitionDelay();
|
||||
final DoubleModel delay = new DoubleModel((delayValue == null ? 0 : delayValue.doubleValue()), UnitGroup.UNITS_NONE, 0d);
|
||||
JSpinner spin = new JSpinner(delay.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin, 3));
|
||||
panel.add(spin, "gap rel rel");
|
||||
|
||||
//// seconds
|
||||
panel.add(new JLabel(FlightConfigurationDialog.trans.get("MotorCfg.lbl.seconds")), "wrap unrel");
|
||||
|
||||
JButton okButton = new JButton(FlightConfigurationDialog.trans.get("button.ok"));
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
//// extract ignition event type;
|
||||
IgnitionConfiguration.IgnitionEvent ignitionEvent = (IgnitionConfiguration.IgnitionEvent) event.getSelectedItem();
|
||||
newConfiguration.setIgnitionEvent(ignitionEvent);
|
||||
|
||||
//// extract ignition delay time;
|
||||
double ignitionDelay = delay.getValue();
|
||||
newConfiguration.setIgnitionDelay(ignitionDelay);
|
||||
|
||||
|
||||
component.setFlightConfiguration(configId, newConfiguration);
|
||||
|
||||
SelectIgnitionConfigDialog.this.setVisible(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
panel.add(okButton);
|
||||
|
||||
JButton cancel = new JButton(FlightConfigurationDialog.trans.get("button.cancel"));
|
||||
cancel.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SelectIgnitionConfigDialog.this.setVisible(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
panel.add(cancel);
|
||||
|
||||
this.setContentPane(panel);
|
||||
this.validate();
|
||||
this.pack();
|
||||
this.setLocationByPlatform(true);
|
||||
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||
|
||||
import java.awt.Dialog;
|
||||
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 javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.adaptors.BasicEnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.components.StyledLabel.Style;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.Stage;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
public class SelectSeparationConfigDialog extends JDialog {
|
||||
|
||||
StageSeparationConfiguration newConfiguration;
|
||||
|
||||
SelectSeparationConfigDialog( JDialog parent, final Rocket rocket, final Stage component ) {
|
||||
super(parent, FlightConfigurationDialog.trans.get("edtmotorconfdlg.title.Selectseparationconf"),Dialog.ModalityType.APPLICATION_MODAL);
|
||||
final String configId = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
|
||||
newConfiguration = component.getFlightConfiguration(configId);
|
||||
if ( newConfiguration == null ) {
|
||||
newConfiguration = component.getDefaultFlightConfiguration().clone();
|
||||
} else {
|
||||
// Clone the existing so cancel works. When the user selects OK, this configuration
|
||||
// is put back in there.
|
||||
newConfiguration = newConfiguration.clone();
|
||||
}
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
// Select separation event
|
||||
panel.add(new StyledLabel(FlightConfigurationDialog.trans.get("StageConfig.separation.lbl.title"), Style.BOLD), "spanx, wrap rel");
|
||||
|
||||
final JComboBox event = new JComboBox(new BasicEnumModel<SeparationEvent>(SeparationEvent.class));
|
||||
event.setSelectedItem( newConfiguration.getSeparationEvent() );
|
||||
panel.add(event, "");
|
||||
|
||||
// ... and delay
|
||||
panel.add(new JLabel(FlightConfigurationDialog.trans.get("StageConfig.separation.lbl.plus")), "");
|
||||
|
||||
final DoubleModel delay = new DoubleModel(newConfiguration.getSeparationDelay(), UnitGroup.UNITS_NONE, 0);
|
||||
JSpinner spin = new JSpinner(delay.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
panel.add(spin, "width 45");
|
||||
|
||||
//// seconds
|
||||
panel.add(new JLabel(FlightConfigurationDialog.trans.get("StageConfig.separation.lbl.seconds")), "wrap unrel");
|
||||
|
||||
|
||||
JButton okButton = new JButton(FlightConfigurationDialog.trans.get("button.ok"));
|
||||
okButton.addActionListener( new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
//// extract event type;
|
||||
SeparationEvent eventType = (SeparationEvent) event.getSelectedItem();
|
||||
newConfiguration.setSeparationEvent(eventType);
|
||||
|
||||
//// extract delay time;
|
||||
double separationDelay = delay.getValue();
|
||||
newConfiguration.setSeparationDelay(separationDelay);
|
||||
|
||||
component.setFlightConfiguration(configId, newConfiguration);
|
||||
|
||||
SelectSeparationConfigDialog.this.setVisible(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
panel.add( okButton );
|
||||
|
||||
JButton cancel = new JButton(FlightConfigurationDialog.trans.get("button.cancel"));
|
||||
cancel.addActionListener( new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SelectSeparationConfigDialog.this.setVisible(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
panel.add( cancel );
|
||||
|
||||
this.setContentPane(panel);
|
||||
this.validate();
|
||||
this.pack();
|
||||
this.setLocationByPlatform(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -15,37 +15,43 @@ import javax.swing.ListSelectionModel;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Stage;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
public class SeparationConfigurationPanel extends JPanel {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private final FlightConfigurationDialog flightConfigurationDialog;
|
||||
private final Rocket rocket;
|
||||
private final Stage[] stages;
|
||||
|
||||
private final JTable separationTable;
|
||||
private final SeparationTableModel separationTableModel;
|
||||
private final JButton selectSeparationButton;
|
||||
private final JButton resetDeploymentButton;
|
||||
|
||||
private Stage selectedComponent;
|
||||
|
||||
SeparationConfigurationPanel( FlightConfigurationDialog flightConfigurationDialog, Rocket rocket ) {
|
||||
super( new MigLayout("fill") );
|
||||
SeparationConfigurationPanel(FlightConfigurationDialog flightConfigurationDialog, Rocket rocket) {
|
||||
super(new MigLayout("fill"));
|
||||
this.flightConfigurationDialog = flightConfigurationDialog;
|
||||
this.rocket = rocket;
|
||||
|
||||
int stageCount = rocket.getStageCount() -1;
|
||||
|
||||
int stageCount = rocket.getStageCount() - 1;
|
||||
stages = new Stage[stageCount];
|
||||
Iterator<RocketComponent> it = rocket.iterator();
|
||||
{
|
||||
int stageIndex = -1;
|
||||
while( it.hasNext() ) {
|
||||
while (it.hasNext()) {
|
||||
RocketComponent c = it.next();
|
||||
if ( c instanceof Stage ) {
|
||||
if ( stageIndex >= 0 ){
|
||||
if (c instanceof Stage) {
|
||||
if (stageIndex >= 0) {
|
||||
stages[stageIndex] = (Stage) c;
|
||||
}
|
||||
stageIndex++;
|
||||
@ -55,38 +61,28 @@ public class SeparationConfigurationPanel extends JPanel {
|
||||
|
||||
//// Recovery selection
|
||||
separationTableModel = new SeparationTableModel();
|
||||
JTable table = new JTable( separationTableModel );
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
table.setRowSelectionAllowed(true);
|
||||
table.addMouseListener(new MouseAdapter() {
|
||||
separationTable = new JTable(separationTableModel);
|
||||
separationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
separationTable.setRowSelectionAllowed(true);
|
||||
separationTable.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
JTable table = (JTable) e.getComponent();
|
||||
int row = table.getSelectedRow();
|
||||
int column = table.getSelectedColumn();
|
||||
|
||||
if ( row >= 0 ) {
|
||||
selectedComponent = stages[row];
|
||||
} else {
|
||||
selectedComponent = null;
|
||||
}
|
||||
|
||||
if (e.getClickCount() == 1) {
|
||||
// FIXME: Listen to selection change, not clicks
|
||||
// Single click updates selection
|
||||
updateButtonState();
|
||||
} else if (e.getClickCount() == 2) {
|
||||
// Double-click edits
|
||||
selectDeployment();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
JScrollPane scroll = new JScrollPane(table);
|
||||
JScrollPane scroll = new JScrollPane(separationTable);
|
||||
this.add(scroll, "span, grow, wrap");
|
||||
|
||||
//// Select deployment
|
||||
selectSeparationButton = new JButton(FlightConfigurationDialog.trans.get("edtmotorconfdlg.but.Selectseparation"));
|
||||
selectSeparationButton = new JButton(trans.get("edtmotorconfdlg.but.Selectseparation"));
|
||||
selectSeparationButton.setEnabled(false);
|
||||
selectSeparationButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@ -97,7 +93,7 @@ public class SeparationConfigurationPanel extends JPanel {
|
||||
this.add(selectSeparationButton, "skip, split, sizegroup button");
|
||||
|
||||
//// Reset deployment
|
||||
resetDeploymentButton = new JButton(FlightConfigurationDialog.trans.get("edtmotorconfdlg.but.Resetseparation"));
|
||||
resetDeploymentButton = new JButton(trans.get("edtmotorconfdlg.but.Resetseparation"));
|
||||
resetDeploymentButton.setEnabled(false);
|
||||
resetDeploymentButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@ -105,35 +101,47 @@ public class SeparationConfigurationPanel extends JPanel {
|
||||
resetDeployment();
|
||||
}
|
||||
});
|
||||
this.add(resetDeploymentButton,"sizegroup button, wrap");
|
||||
this.add(resetDeploymentButton, "sizegroup button, wrap");
|
||||
|
||||
}
|
||||
|
||||
public void fireTableDataChanged() {
|
||||
selectedComponent = null;
|
||||
separationTableModel.fireTableDataChanged();
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
private Stage getSelectedStage() {
|
||||
int row = separationTable.getSelectedRow();
|
||||
if (row >= 0 && row < stages.length) {
|
||||
return stages[row];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void selectDeployment() {
|
||||
JDialog d = new SelectSeparationConfigDialog( flightConfigurationDialog, rocket, selectedComponent );
|
||||
Stage stage = getSelectedStage();
|
||||
if (stage == null) {
|
||||
return;
|
||||
}
|
||||
JDialog d = new SeparationSelectionDialog(flightConfigurationDialog, rocket, stage);
|
||||
d.setVisible(true);
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
private void resetDeployment() {
|
||||
selectedComponent.setFlightConfiguration(rocket.getDefaultConfiguration().getFlightConfigurationID(), null);
|
||||
Stage stage = getSelectedStage();
|
||||
if (stage == null) {
|
||||
return;
|
||||
}
|
||||
String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
stage.getStageSeparationConfiguration().resetDefault(id);
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
public void updateButtonState() {
|
||||
boolean componentSelected = selectedComponent != null;
|
||||
boolean isDefaulted = true;
|
||||
if ( componentSelected ) {
|
||||
isDefaulted = selectedComponent.getFlightConfiguration(rocket.getDefaultConfiguration().getFlightConfigurationID()) == null;
|
||||
}
|
||||
boolean componentSelected = getSelectedStage() != null;
|
||||
selectSeparationButton.setEnabled(componentSelected);
|
||||
resetDeploymentButton.setEnabled(componentSelected & ! isDefaulted);
|
||||
resetDeploymentButton.setEnabled(componentSelected);
|
||||
}
|
||||
|
||||
private class SeparationTableModel extends AbstractTableModel {
|
||||
@ -151,28 +159,37 @@ public class SeparationConfigurationPanel extends JPanel {
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
Stage d = SeparationConfigurationPanel.this.stages[rowIndex];
|
||||
switch ( columnIndex ) {
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return d.getName();
|
||||
case 1:
|
||||
StageSeparationConfiguration separationConfig = d.getFlightConfiguration(rocket.getDefaultConfiguration().getFlightConfigurationID());
|
||||
if ( separationConfig == null ) {
|
||||
return "[" + d.getDefaultFlightConfiguration().toString() + "]";
|
||||
String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
StageSeparationConfiguration separationConfig = d.getStageSeparationConfiguration().get(id);
|
||||
|
||||
SeparationEvent event = separationConfig.getSeparationEvent();
|
||||
String str = event.toString();
|
||||
|
||||
if (d.getStageSeparationConfiguration().isDefault(id)) {
|
||||
str = trans.get("SeparationConfigurationPanel.table.separation.default");
|
||||
str = str.replace("{0}", event.toString());
|
||||
} else {
|
||||
return separationConfig.toString();
|
||||
str = event.toString();
|
||||
}
|
||||
return str;
|
||||
|
||||
default:
|
||||
throw new IndexOutOfBoundsException("column=" + columnIndex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
switch ( column ) {
|
||||
switch (column) {
|
||||
case 0:
|
||||
return FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Stageheader");
|
||||
return trans.get("edtmotorconfdlg.tbl.Stageheader");
|
||||
case 1:
|
||||
return FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Separationheader");
|
||||
return trans.get("edtmotorconfdlg.tbl.Separationheader");
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
@ -0,0 +1,91 @@
|
||||
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||
|
||||
import java.awt.Dialog;
|
||||
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 javax.swing.JPanel;
|
||||
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.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.Stage;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
public class SeparationSelectionDialog extends JDialog {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private StageSeparationConfiguration newConfiguration;
|
||||
|
||||
SeparationSelectionDialog(JDialog parent, final Rocket rocket, final Stage component) {
|
||||
super(parent, trans.get("edtmotorconfdlg.title.Selectseparationconf"), Dialog.ModalityType.APPLICATION_MODAL);
|
||||
final String id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
|
||||
newConfiguration = component.getStageSeparationConfiguration().get(id).clone();
|
||||
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
// FIXME: Edit Default or override option
|
||||
|
||||
// Select separation event
|
||||
panel.add(new JLabel(trans.get("SeparationSelectionDialog.lbl.separation")), "");
|
||||
|
||||
final JComboBox event = new JComboBox(new EnumModel<SeparationEvent>(newConfiguration, "SeparationEvent"));
|
||||
event.setSelectedItem(newConfiguration.getSeparationEvent());
|
||||
panel.add(event, "wrap rel");
|
||||
|
||||
// ... and delay
|
||||
panel.add(new JLabel(trans.get("StageConfig.separation.lbl.plus")), "alignx 100%");
|
||||
|
||||
final DoubleModel delay = new DoubleModel(newConfiguration, "SeparationDelay", UnitGroup.UNITS_SHORT_TIME, 0);
|
||||
JSpinner spin = new JSpinner(delay.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin, 3));
|
||||
panel.add(spin, "span, split");
|
||||
|
||||
//// seconds
|
||||
panel.add(new JLabel(trans.get("StageConfig.separation.lbl.seconds")), "wrap para");
|
||||
|
||||
|
||||
panel.add(new JPanel(), "span, split, growx");
|
||||
|
||||
JButton okButton = new JButton(trans.get("button.ok"));
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
component.getStageSeparationConfiguration().set(id, newConfiguration);
|
||||
SeparationSelectionDialog.this.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(okButton, "sizegroup btn");
|
||||
|
||||
JButton cancel = new JButton(trans.get("button.cancel"));
|
||||
cancel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SeparationSelectionDialog.this.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(cancel, "sizegroup btn");
|
||||
|
||||
this.setContentPane(panel);
|
||||
|
||||
GUIUtil.setDisposableDialogOptions(this, okButton);
|
||||
}
|
||||
|
||||
}
|
@ -160,7 +160,7 @@ public class SimulationModifierTree extends BasicTree {
|
||||
RocketComponent c = (RocketComponent) object;
|
||||
String comment = c.getComment().trim();
|
||||
if (comment.length() > 0) {
|
||||
comment = TextUtil.htmlEncode(comment);
|
||||
comment = TextUtil.escapeXML(comment);
|
||||
comment = "<html>" + comment.replace("\n", "<br>");
|
||||
this.setToolTipText(comment);
|
||||
} else {
|
||||
|
@ -48,7 +48,7 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer {
|
||||
|
||||
String comment = c.getComment().trim();
|
||||
if (comment.length() > 0) {
|
||||
comment = TextUtil.htmlEncode(comment);
|
||||
comment = TextUtil.escapeXML(comment);
|
||||
comment = comment.replace("\n", "<br>");
|
||||
sb.append("<br>").append(comment);
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import net.sf.openrocket.optimization.general.OptimizationException;
|
||||
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier;
|
||||
import net.sf.openrocket.optimization.rocketoptimization.modifiers.GenericComponentModifier;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
|
||||
@ -24,7 +23,6 @@ import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||
import net.sf.openrocket.rocketcomponent.Parachute;
|
||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Streamer;
|
||||
@ -243,29 +241,31 @@ public class DefaultSimulationModifierService implements SimulationModifierServi
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Reimplement for flight-configuration controlled modifiers
|
||||
|
||||
// Recovery device deployment altitude and delay
|
||||
if (c instanceof RecoveryDevice) {
|
||||
RecoveryDevice device = (RecoveryDevice) c;
|
||||
|
||||
SimulationModifier mod = new GenericComponentModifier(
|
||||
trans.get("optimization.modifier.recoverydevice.deployDelay"),
|
||||
trans.get("optimization.modifier.recoverydevice.deployDelay.desc"),
|
||||
c, UnitGroup.UNITS_SHORT_TIME,
|
||||
1.0, c.getClass(), c.getID(), "DefaultDeployDelay");
|
||||
mod.setMinValue(0);
|
||||
mod.setMaxValue(10);
|
||||
modifiers.add(mod);
|
||||
|
||||
if (device.getDefaultDeployEvent() == DeployEvent.ALTITUDE) {
|
||||
mod = new GenericComponentModifier(
|
||||
trans.get("optimization.modifier.recoverydevice.deployAltitude"),
|
||||
trans.get("optimization.modifier.recoverydevice.deployAltitude.desc"),
|
||||
c, UnitGroup.UNITS_DISTANCE,
|
||||
1.0, c.getClass(), c.getID(), "DefaultDeployAltitude");
|
||||
setDefaultMinMax(mod, simulation);
|
||||
modifiers.add(mod);
|
||||
}
|
||||
}
|
||||
// if (c instanceof RecoveryDevice) {
|
||||
// RecoveryDevice device = (RecoveryDevice) c;
|
||||
//
|
||||
// SimulationModifier mod = new GenericComponentModifier(
|
||||
// trans.get("optimization.modifier.recoverydevice.deployDelay"),
|
||||
// trans.get("optimization.modifier.recoverydevice.deployDelay.desc"),
|
||||
// c, UnitGroup.UNITS_SHORT_TIME,
|
||||
// 1.0, c.getClass(), c.getID(), "DefaultDeployDelay");
|
||||
// mod.setMinValue(0);
|
||||
// mod.setMaxValue(10);
|
||||
// modifiers.add(mod);
|
||||
//
|
||||
// if (device.getDefaultDeployEvent() == DeployEvent.ALTITUDE) {
|
||||
// mod = new GenericComponentModifier(
|
||||
// trans.get("optimization.modifier.recoverydevice.deployAltitude"),
|
||||
// trans.get("optimization.modifier.recoverydevice.deployAltitude.desc"),
|
||||
// c, UnitGroup.UNITS_DISTANCE,
|
||||
// 1.0, c.getClass(), c.getID(), "DefaultDeployAltitude");
|
||||
// setDefaultMinMax(mod, simulation);
|
||||
// modifiers.add(mod);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// Conditional shape parameter of Transition
|
||||
|
@ -38,7 +38,7 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
|
||||
this.outerRadius = DEFAULT_RADIUS;
|
||||
this.autoRadius = true;
|
||||
|
||||
this.motorConfigurations = new FlightConfigurationImpl<MotorConfiguration>(this, ComponentChangeEvent.MOTOR_CHANGE, new MotorConfiguration());
|
||||
this.motorConfigurations = new MotorFlightConfigurationImpl<MotorConfiguration>(this, ComponentChangeEvent.MOTOR_CHANGE, MotorConfiguration.NO_MOTORS);
|
||||
this.ignitionConfigurations = new FlightConfigurationImpl<IgnitionConfiguration>(this, ComponentChangeEvent.EVENT_CHANGE, new IgnitionConfiguration());
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import net.sf.openrocket.util.StateChangeListener;
|
||||
|
||||
public class IgnitionConfiguration implements FlightConfigurableParameter<IgnitionConfiguration> {
|
||||
|
||||
public static enum IgnitionEvent {
|
||||
public enum IgnitionEvent {
|
||||
//// Automatic (launch or ejection charge)
|
||||
AUTOMATIC("MotorMount.IgnitionEvent.AUTOMATIC") {
|
||||
@Override
|
||||
@ -104,11 +104,11 @@ public class IgnitionConfiguration implements FlightConfigurableParameter<Igniti
|
||||
}
|
||||
|
||||
|
||||
public double getDelay() {
|
||||
public double getIgnitionDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
public void setDelay(double delay) {
|
||||
public void setIgnitionDelay(double delay) {
|
||||
if (MathUtil.equals(delay, this.delay)) {
|
||||
return;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
||||
this.setInnerRadius(0.018 / 2);
|
||||
this.setLength(0.070);
|
||||
|
||||
this.motorConfigurations = new FlightConfigurationImpl<MotorConfiguration>(this, ComponentChangeEvent.MOTOR_CHANGE, new MotorConfiguration());
|
||||
this.motorConfigurations = new MotorFlightConfigurationImpl<MotorConfiguration>(this, ComponentChangeEvent.MOTOR_CHANGE, MotorConfiguration.NO_MOTORS);
|
||||
this.ignitionConfigurations = new FlightConfigurationImpl<IgnitionConfiguration>(this, ComponentChangeEvent.EVENT_CHANGE, new IgnitionConfiguration());
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,19 @@ import net.sf.openrocket.util.Utils;
|
||||
*/
|
||||
public class MotorConfiguration implements FlightConfigurableParameter<MotorConfiguration> {
|
||||
|
||||
/** Immutable configuration with no motor and zero delay. */
|
||||
public static final MotorConfiguration NO_MOTORS = new MotorConfiguration() {
|
||||
@Override
|
||||
public void setMotor(Motor motor) {
|
||||
throw new UnsupportedOperationException("Trying to modify immutable no-motors configuration");
|
||||
};
|
||||
|
||||
@Override
|
||||
public void setEjectionDelay(double delay) {
|
||||
throw new UnsupportedOperationException("Trying to modify immutable no-motors configuration");
|
||||
};
|
||||
};
|
||||
|
||||
private final List<StateChangeListener> listeners = new ArrayList<StateChangeListener>();
|
||||
|
||||
private Motor motor;
|
||||
|
@ -0,0 +1,18 @@
|
||||
package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
/**
|
||||
* FlightConfiguration implementation that prevents changing the default value.
|
||||
* This is used for motors, where the default value is always no motor.
|
||||
*/
|
||||
public class MotorFlightConfigurationImpl<E extends FlightConfigurableParameter<E>> extends FlightConfigurationImpl<E> {
|
||||
|
||||
public MotorFlightConfigurationImpl(RocketComponent component, int eventType, E defaultValue) {
|
||||
super(component, eventType, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefault(E value) {
|
||||
throw new UnsupportedOperationException("Cannot change default value of motor configuration");
|
||||
}
|
||||
|
||||
}
|
@ -243,7 +243,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
Coordinate position = positions[i];
|
||||
MotorId id = new MotorId(component.getID(), i + 1);
|
||||
motors.addMotor(id, motor.getInstance(), motorConfig.getEjectionDelay(), mount,
|
||||
ignitionConfig.getIgnitionEvent(), ignitionConfig.getDelay(), position);
|
||||
ignitionConfig.getIgnitionEvent(), ignitionConfig.getIgnitionDelay(), position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,13 @@ package net.sf.openrocket.util;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
||||
|
||||
public class Reflection {
|
||||
|
||||
private static final String ROCKETCOMPONENT_PACKAGE = "net.sf.openrocket.rocketcomponent";
|
||||
|
||||
/**
|
||||
* Simple wrapper class that converts the Method.invoke() exceptions into suitable
|
||||
* RuntimeExceptions.
|
||||
@ -90,19 +89,18 @@ public class Reflection {
|
||||
|
||||
|
||||
/**
|
||||
* Find a method from the rocket component classes.
|
||||
* Find a method from a class.
|
||||
* Throws an exception if method not found.
|
||||
*/
|
||||
public static Reflection.Method findMethod(
|
||||
Class<? extends RocketComponent> componentClass,
|
||||
String method, Class<?>... params) {
|
||||
Reflection.Method m = findMethod(ROCKETCOMPONENT_PACKAGE, componentClass,
|
||||
"", method, params);
|
||||
if (m == null) {
|
||||
throw new BugException("Could not find method for componentClass="
|
||||
+ componentClass + " method=" + method);
|
||||
public static Reflection.Method findMethod(Class<?> c, String method, Class<?>... params) {
|
||||
|
||||
java.lang.reflect.Method m;
|
||||
try {
|
||||
m = c.getMethod(method, params);
|
||||
return new Reflection.Method(m);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new BugException("Could not find method " + method + "(" + Arrays.toString(params) + ") from class " + c);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,9 +42,9 @@ public class TextUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string of the double value with suitable precision (5 digits).
|
||||
* The string is the shortest representation of the value including the
|
||||
* required precision.
|
||||
* Return a string of the double value with suitable precision for storage.
|
||||
* The string is the shortest representation of the value including at least
|
||||
* 5 digits of precision.
|
||||
*
|
||||
* @param d the value to present.
|
||||
* @return a representation with suitable precision.
|
||||
@ -172,26 +172,42 @@ public class TextUtil {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String htmlEncode(String s) {
|
||||
s = s.replace("&", "&");
|
||||
s = s.replace("\"", """);
|
||||
s = s.replace("<", "<");
|
||||
s = s.replace(">", ">");
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a word-wrapped version of given input string using HTML syntax, wrapped to len characters.
|
||||
/**
|
||||
* Escape a string as XML or HTML. Encodes the following characters:
|
||||
* <ul>
|
||||
* <li>less than, greater than
|
||||
* <li>quotation mark, apostrophe
|
||||
* <li>ampersand
|
||||
* <li>all control characters except newline, carriage return and tab
|
||||
* </ul>
|
||||
*
|
||||
* The result is both valid XML and HTML 2.0. The majority of characters are left unchanged.
|
||||
*/
|
||||
public static String wrap(String in, int len) {
|
||||
in = in.trim();
|
||||
if (in.length() < len)
|
||||
return in;
|
||||
if (in.substring(0, len).contains("\n"))
|
||||
return in.substring(0, in.indexOf("\n")).trim() + "\n\n" + wrap(in.substring(in.indexOf("\n") + 1), len);
|
||||
int place = Math.max(Math.max(in.lastIndexOf(" ", len), in.lastIndexOf("\t", len)), in.lastIndexOf("-", len));
|
||||
return "<html>" + in.substring(0, place).trim() + "<br>" + wrap(in.substring(place), len);
|
||||
public static String escapeXML(String s) {
|
||||
StringBuilder sb = new StringBuilder(s.length());
|
||||
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
|
||||
if (c == '&') {
|
||||
sb.append("&");
|
||||
} else if (c == '<') {
|
||||
sb.append("<");
|
||||
} else if (c == '>') {
|
||||
sb.append(">");
|
||||
} else if (c == '"') {
|
||||
sb.append(""");
|
||||
} else if (((c < 32) && (c != '\t') && (c != '\n') && (c != '\r')) || (c == '\'') || (c == 127)) {
|
||||
// ' is not used since it's not standard HTML, use numerical escape instead
|
||||
sb.append("&#").append((int) c).append(';');
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -278,4 +278,15 @@ public class TextUtilTest {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEscapeXML() {
|
||||
assertEquals("", TextUtil.escapeXML(""));
|
||||
assertEquals("foo&bar", TextUtil.escapeXML("foo&bar"));
|
||||
assertEquals("<html>&", TextUtil.escapeXML("<html>&"));
|
||||
assertEquals(""'", TextUtil.escapeXML("\"'"));
|
||||
assertEquals("foo\n\r\tbar", TextUtil.escapeXML("foo\n\r\tbar"));
|
||||
assertEquals("foo�bar", TextUtil.escapeXML("foo" + ((char) 0) + ((char) 1) + ((char) 31) + ((char) 127) + "bar"));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user