updates
This commit is contained in:
parent
2f7baaa87c
commit
0d0db9258e
@ -1,3 +1,12 @@
|
||||
2009-06-08 Sampo Niskanen
|
||||
|
||||
* Fixed loading of icons from JAR
|
||||
|
||||
2009-06-06 Sampo Niskanen
|
||||
|
||||
* Cut/Copy/Paste of simulations
|
||||
* Improved build scripts
|
||||
|
||||
2009-05-28 Sampo Niskanen
|
||||
|
||||
* Added startup check for Java 1.6 and OpenJDK
|
||||
|
8
build.properties
Normal file
8
build.properties
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
# The OpenRocket build version
|
||||
build.version=0.9.1pre
|
||||
|
||||
# The source of the package. When building a package for a specific
|
||||
# distribution (Debian, Fedora etc.), this should be changed appropriately!
|
||||
build.source=default
|
||||
|
72
build.xml
72
build.xml
@ -1,18 +1,25 @@
|
||||
<project name="OpenRocket" basedir=".">
|
||||
|
||||
<property file="build.properties" />
|
||||
|
||||
<property name="src.dir" value="src"/> <!-- Source directory -->
|
||||
<property name="build.dir" value="build"/> <!-- Build directory -->
|
||||
|
||||
<!-- Distribution directory, from which stuff is jar'ed -->
|
||||
<property name="dist.dir" value="${build.dir}/dist"/>
|
||||
<property name="test.dir" value="${build.dir}/test"/>
|
||||
|
||||
<property name="classes.dir" value="${dist.dir}"/> <!-- Directory for classes -->
|
||||
<property name="jar.dir" value="${build.dir}/jar"/> <!-- Directory for built jar's -->
|
||||
<property name="lib.dir" value="lib"/> <!-- Library source directory -->
|
||||
|
||||
<property name="jar.file" value="${jar.dir}/${ant.project.name}.jar"/>
|
||||
<property name="dist.bin" value="${jar.dir}/${ant.project.name}-${build.version}.jar"/>
|
||||
<property name="dist.src" value="${jar.dir}/${ant.project.name}-src-${build.version}.zip"/>
|
||||
|
||||
<!-- The main class of the application -->
|
||||
<property name="main-class" value="net.sf.openrocket.startup.Startup"/>
|
||||
<property name="main-dir" value="net/sf/openrocket/startup"/>
|
||||
|
||||
|
||||
<!-- Classpath definition -->
|
||||
@ -21,26 +28,32 @@
|
||||
</path>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- CLEAN -->
|
||||
<target name="clean">
|
||||
<delete dir="${build.dir}"/>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- BUILD -->
|
||||
<target name="build">
|
||||
<mkdir dir="${classes.dir}"/>
|
||||
<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
|
||||
<echo>Compiling main classes</echo>
|
||||
<javac srcdir="${src.dir}" destdir="${classes.dir}" excludes="${main-dir}/*" classpathref="classpath"/>
|
||||
<echo>Compiling startup classes</echo>
|
||||
<javac srcdir="${src.dir}/${main-dir}" destdir="${classes.dir}" source="1.4" classpathref="classpath"/>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- JAR -->
|
||||
<target name="jar" depends="build">
|
||||
<copy todir="${dist.dir}/">
|
||||
<fileset dir="." includes="LICENSE.TXT" />
|
||||
<fileset dir="." includes="README.TXT" />
|
||||
<fileset dir="." includes="datafiles/**/* pix/**/*" />
|
||||
<fileset dir="." includes="LICENSE.TXT README.TXT build.properties" />
|
||||
<fileset dir="." includes="datafiles/ pix/" />
|
||||
</copy>
|
||||
<mkdir dir="${jar.dir}"/>
|
||||
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${dist.dir}">
|
||||
<jar destfile="${jar.file}" basedir="${dist.dir}">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="${main-class}"/>
|
||||
<attribute name="SplashScreen-Image" value="pix/splashscreen.png"/>
|
||||
@ -51,13 +64,48 @@
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<!-- RUN -->
|
||||
<target name="run" depends="jar">
|
||||
<java fork="true" classname="${main-class}">
|
||||
<classpath>
|
||||
<path location="${jar.dir}/${ant.project.name}.jar"/>
|
||||
</classpath>
|
||||
</java>
|
||||
|
||||
<!-- DIST-SRC -->
|
||||
<target name="dist-src" depends="clean">
|
||||
<echo>
|
||||
Building source distribution
|
||||
</echo>
|
||||
<mkdir dir="${jar.dir}"/>
|
||||
<zip destfile="${dist.src}">
|
||||
<!-- Base directory: -->
|
||||
<fileset dir="." includes="*">
|
||||
<type type="file"/>
|
||||
</fileset>
|
||||
<fileset dir="." includes="datafiles/ lib/ pix/ src/"/>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- DIST-SRC-TEST -->
|
||||
<target name="dist-src-test" depends="dist-src">
|
||||
<echo>
|
||||
Testing source distribution
|
||||
</echo>
|
||||
<delete dir="${test.dir}"/>
|
||||
<mkdir dir="${test.dir}"/>
|
||||
<unzip dest="${test.dir}" src="${dist.src}"/>
|
||||
<ant dir="${test.dir}" antfile="build.xml" target="jar"/>
|
||||
<delete dir="${test.dir}"/>
|
||||
<echo>
|
||||
Test successful
|
||||
</echo>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- DIST-BIN -->
|
||||
<target name="dist-bin" depends="clean,jar">
|
||||
<move file="${jar.file}" tofile="${dist.bin}"/>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- DIST -->
|
||||
<target name="dist" depends="dist-bin,dist-src,dist-src-test">
|
||||
<echo>Distribution ${build.version} (${build.source}) built into directory ${jar.dir}</echo>
|
||||
</target>
|
||||
|
||||
</project>
|
BIN
dists/OpenRocket-0.9.0.jar
Normal file
BIN
dists/OpenRocket-0.9.0.jar
Normal file
Binary file not shown.
@ -101,6 +101,19 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript">
|
||||
var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/openrocket/" : "http://apps.sourceforge.net/piwik/openrocket/");
|
||||
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script><script type="text/javascript">
|
||||
piwik_action_name = '';
|
||||
piwik_idsite = 1;
|
||||
piwik_url = pkBaseURL + "piwik.php";
|
||||
piwik_log(piwik_action_name, piwik_idsite, piwik_url);
|
||||
</script>
|
||||
<noscript><p><img src="http://apps.sourceforge.net/piwik/openrocket/piwik.php?idsite=1" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -175,6 +175,19 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript">
|
||||
var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/openrocket/" : "http://apps.sourceforge.net/piwik/openrocket/");
|
||||
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script><script type="text/javascript">
|
||||
piwik_action_name = '';
|
||||
piwik_idsite = 1;
|
||||
piwik_url = pkBaseURL + "piwik.php";
|
||||
piwik_log(piwik_action_name, piwik_idsite, piwik_url);
|
||||
</script>
|
||||
<noscript><p><img src="http://apps.sourceforge.net/piwik/openrocket/piwik.php?idsite=1" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
||||
later. The Sun JRE is recommended.</em></p>
|
||||
|
||||
<p class="download">
|
||||
<a href="https://sourceforge.net/project/downloading.php?group_id=260357&filename=OpenRocket-0.9.0.jar">Download OpenRocket 0.9.0</a></p>
|
||||
<a href="https://sourceforge.net/project/downloading.php?group_id=260357&filename=OpenRocket-0.9.0.jar">Download OpenRocket 0.9.0</a></p>
|
||||
|
||||
<p>OpenRocket is still considered <strong>beta software</strong>.
|
||||
If you encounter any problems, please
|
||||
@ -90,6 +90,19 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript">
|
||||
var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/openrocket/" : "http://apps.sourceforge.net/piwik/openrocket/");
|
||||
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script><script type="text/javascript">
|
||||
piwik_action_name = '';
|
||||
piwik_idsite = 1;
|
||||
piwik_url = pkBaseURL + "piwik.php";
|
||||
piwik_log(piwik_action_name, piwik_idsite, piwik_url);
|
||||
</script>
|
||||
<noscript><p><img src="http://apps.sourceforge.net/piwik/openrocket/piwik.php?idsite=1" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -139,6 +139,19 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript">
|
||||
var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/openrocket/" : "http://apps.sourceforge.net/piwik/openrocket/");
|
||||
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script><script type="text/javascript">
|
||||
piwik_action_name = '';
|
||||
piwik_idsite = 1;
|
||||
piwik_url = pkBaseURL + "piwik.php";
|
||||
piwik_log(piwik_action_name, piwik_idsite, piwik_url);
|
||||
</script>
|
||||
<noscript><p><img src="http://apps.sourceforge.net/piwik/openrocket/piwik.php?idsite=1" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -101,6 +101,19 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript">
|
||||
var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/openrocket/" : "http://apps.sourceforge.net/piwik/openrocket/");
|
||||
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script><script type="text/javascript">
|
||||
piwik_action_name = '';
|
||||
piwik_idsite = 1;
|
||||
piwik_url = pkBaseURL + "piwik.php";
|
||||
piwik_log(piwik_action_name, piwik_idsite, piwik_url);
|
||||
</script>
|
||||
<noscript><p><img src="http://apps.sourceforge.net/piwik/openrocket/piwik.php?idsite=1" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -764,6 +764,19 @@ Public License instead of this License. But first, please read
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript">
|
||||
var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/openrocket/" : "http://apps.sourceforge.net/piwik/openrocket/");
|
||||
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script><script type="text/javascript">
|
||||
piwik_action_name = '';
|
||||
piwik_idsite = 1;
|
||||
piwik_url = pkBaseURL + "piwik.php";
|
||||
piwik_log(piwik_action_name, piwik_idsite, piwik_url);
|
||||
</script>
|
||||
<noscript><p><img src="http://apps.sourceforge.net/piwik/openrocket/piwik.php?idsite=1" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -55,9 +55,9 @@
|
||||
<ul>
|
||||
<li>Search the bug repository to see if the bug has already been
|
||||
reported. If it is, please add extra information to that bug
|
||||
report:<br/>
|
||||
report:
|
||||
<form action="https://sourceforge.net/search/index.php" method="get">
|
||||
<input type="hidden" name="group_id" value="260357" />
|
||||
<p><input type="hidden" name="group_id" value="260357" />
|
||||
<input type="hidden" name="type_of_search" value="artifact"/>
|
||||
<!-- <input type="hidden" name="group_artifact_id" value="1127606" /> -->
|
||||
<!-- <input type="hidden" name="artifact_group" value="Bug" /> -->
|
||||
@ -66,12 +66,12 @@
|
||||
<input type="hidden" name="search_comments" value="1" />
|
||||
|
||||
<input type="text" name="all_words" value="" />
|
||||
<input type="submit" name="form_submit" value="Search" />
|
||||
<input type="submit" name="form_submit" value="Search" /></p>
|
||||
</form>
|
||||
</li>
|
||||
|
||||
<li>Report the bug using the
|
||||
<a href="https://sourceforge.net/tracker/?func=add&group_id=260357&atid=1127606">bug
|
||||
<a href="https://sourceforge.net/tracker/?func=add&group_id=260357&atid=1127606">bug
|
||||
tracker</a>. Follow the instructions provided to fill in the
|
||||
report.</li>
|
||||
|
||||
@ -97,8 +97,8 @@
|
||||
<ul>
|
||||
<li>Check that the feature is not already in the
|
||||
<a href="features.html#future">planned future features</a> or
|
||||
the <a href="https://sourceforge.net/tracker/?group_id=260357&atid=1127606&artgroup=899287">enhancement requests</a>.</li>
|
||||
<li>Send the request to the <a href="https://sourceforge.net/tracker/?func=add&group_id=260357&atid=1127606">bug tracker</a> as an
|
||||
the <a href="https://sourceforge.net/tracker/?group_id=260357&atid=1127606&artgroup=899287">enhancement requests</a>.</li>
|
||||
<li>Send the request to the <a href="https://sourceforge.net/tracker/?func=add&group_id=260357&atid=1127606">bug tracker</a> as an
|
||||
enhancement request. Please send multiple enhancements as
|
||||
individual items.</li>
|
||||
</ul>
|
||||
@ -111,6 +111,19 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript">
|
||||
var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/openrocket/" : "http://apps.sourceforge.net/piwik/openrocket/");
|
||||
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script><script type="text/javascript">
|
||||
piwik_action_name = '';
|
||||
piwik_idsite = 1;
|
||||
piwik_url = pkBaseURL + "piwik.php";
|
||||
piwik_log(piwik_action_name, piwik_idsite, piwik_url);
|
||||
</script>
|
||||
<noscript><p><img src="http://apps.sourceforge.net/piwik/openrocket/piwik.php?idsite=1" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -90,6 +90,19 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript">
|
||||
var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/openrocket/" : "http://apps.sourceforge.net/piwik/openrocket/");
|
||||
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script><script type="text/javascript">
|
||||
piwik_action_name = '';
|
||||
piwik_idsite = 1;
|
||||
piwik_url = pkBaseURL + "piwik.php";
|
||||
piwik_log(piwik_action_name, piwik_idsite, piwik_url);
|
||||
</script>
|
||||
<noscript><p><img src="http://apps.sourceforge.net/piwik/openrocket/piwik.php?idsite=1" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -10,6 +10,9 @@ import java.util.List;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
|
||||
import net.sf.openrocket.document.events.DocumentChangeEvent;
|
||||
import net.sf.openrocket.document.events.DocumentChangeListener;
|
||||
import net.sf.openrocket.document.events.SimulationChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
@ -29,6 +32,8 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
||||
public static final int UNDO_MARGIN = 10;
|
||||
|
||||
|
||||
public static final String SIMULATION_NAME_PREFIX = "Simulation ";
|
||||
|
||||
private final Rocket rocket;
|
||||
private final Configuration configuration;
|
||||
|
||||
@ -48,6 +53,9 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
||||
private final StorageOptions storageOptions = new StorageOptions();
|
||||
|
||||
|
||||
private final List<DocumentChangeListener> listeners =
|
||||
new ArrayList<DocumentChangeListener>();
|
||||
|
||||
/* These must be initialized after undo history is set up. */
|
||||
private final UndoRedoAction undoAction;
|
||||
private final UndoRedoAction redoAction;
|
||||
@ -70,8 +78,6 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
||||
redoAction = new UndoRedoAction(UndoRedoAction.REDO);
|
||||
|
||||
rocket.addComponentChangeListener(this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -135,17 +141,43 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
||||
}
|
||||
public void addSimulation(Simulation simulation) {
|
||||
simulations.add(simulation);
|
||||
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
||||
}
|
||||
public void addSimulation(Simulation simulation, int n) {
|
||||
simulations.add(n, simulation);
|
||||
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
||||
}
|
||||
public void removeSimulation(Simulation simulation) {
|
||||
simulations.remove(simulation);
|
||||
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
||||
}
|
||||
public Simulation removeSimulation(int n) {
|
||||
return simulations.remove(n);
|
||||
Simulation simulation = simulations.remove(n);
|
||||
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
||||
return simulation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a unique name suitable for the next simulation. The name begins
|
||||
* with {@link #SIMULATION_NAME_PREFIX} and has a unique number larger than any
|
||||
* previous simulation.
|
||||
*
|
||||
* @return the new name.
|
||||
*/
|
||||
public String getNextSimulationName() {
|
||||
// Generate unique name for the simulation
|
||||
int maxValue = 0;
|
||||
for (Simulation s: simulations) {
|
||||
String name = s.getName();
|
||||
if (name.startsWith(SIMULATION_NAME_PREFIX)) {
|
||||
try {
|
||||
maxValue = Math.max(maxValue,
|
||||
Integer.parseInt(name.substring(SIMULATION_NAME_PREFIX.length())));
|
||||
} catch (NumberFormatException ignore) { }
|
||||
}
|
||||
}
|
||||
return SIMULATION_NAME_PREFIX + (maxValue+1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -301,6 +333,24 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
||||
|
||||
|
||||
|
||||
/////// Listeners
|
||||
|
||||
public void addDocumentChangeListener(DocumentChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeDocumentChangeListener(DocumentChangeListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
protected void fireDocumentChangeEvent(DocumentChangeEvent event) {
|
||||
DocumentChangeListener[] array = listeners.toArray(new DocumentChangeListener[0]);
|
||||
for (DocumentChangeListener l: array) {
|
||||
l.documentChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,7 @@ import net.sf.openrocket.simulation.exception.SimulationListenerException;
|
||||
import net.sf.openrocket.util.ChangeSource;
|
||||
|
||||
|
||||
public class Simulation implements ChangeSource {
|
||||
public class Simulation implements ChangeSource, Cloneable {
|
||||
|
||||
public static enum Status {
|
||||
/** Up-to-date */
|
||||
@ -48,9 +48,9 @@ public class Simulation implements ChangeSource {
|
||||
private Status status = Status.NOT_SIMULATED;
|
||||
|
||||
/** The conditions to use */
|
||||
private final SimulationConditions conditions;
|
||||
private SimulationConditions conditions;
|
||||
|
||||
private List<String> simulationListeners = new ArrayList<String>();
|
||||
private ArrayList<String> simulationListeners = new ArrayList<String>();
|
||||
|
||||
private Class<? extends FlightSimulator> simulatorClass = RK4Simulator.class;
|
||||
private Class<? extends AerodynamicCalculator> calculatorClass = BarrowmanCalculator.class;
|
||||
@ -58,7 +58,7 @@ public class Simulation implements ChangeSource {
|
||||
|
||||
|
||||
/** Listeners for this object */
|
||||
private final List<ChangeListener> listeners = new ArrayList<ChangeListener>();
|
||||
private List<ChangeListener> listeners = new ArrayList<ChangeListener>();
|
||||
|
||||
|
||||
/** The conditions actually used in the previous simulation, or null */
|
||||
@ -304,7 +304,7 @@ public class Simulation implements ChangeSource {
|
||||
*
|
||||
* @return a description of the motor configuration of the previous simulation, or
|
||||
* <code>null</code>.
|
||||
* @see Rocket#getMotorConfigurationDescription(String)
|
||||
* @see Rocket#getMotorConfigurationNameOrDescription(String)
|
||||
*/
|
||||
public String getSimulatedMotorDescription() {
|
||||
return simulatedMotors;
|
||||
@ -321,7 +321,56 @@ public class Simulation implements ChangeSource {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a copy of this simulation suitable for cut/copy/paste operations.
|
||||
* This excludes any simulated data.
|
||||
*
|
||||
* @return a copy of this simulation and its conditions.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Simulation copy() {
|
||||
try {
|
||||
|
||||
Simulation copy = (Simulation)super.clone();
|
||||
|
||||
copy.status = Status.NOT_SIMULATED;
|
||||
copy.conditions = this.conditions.clone();
|
||||
copy.simulationListeners = (ArrayList<String>) this.simulationListeners.clone();
|
||||
copy.listeners = new ArrayList<ChangeListener>();
|
||||
copy.simulatedConditions = null;
|
||||
copy.simulatedMotors = null;
|
||||
copy.simulatedData = null;
|
||||
copy.simulatedRocketID = -1;
|
||||
|
||||
return copy;
|
||||
|
||||
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException("Clone not supported, BUG", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a duplicate of this simulation with the specified rocket. The new
|
||||
* simulation is in non-simulated state.
|
||||
*
|
||||
* @param newRocket the rocket for the new simulation.
|
||||
* @return a new simulation with the same conditions and properties.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Simulation duplicateSimulation(Rocket newRocket) {
|
||||
Simulation copy = new Simulation(newRocket);
|
||||
|
||||
copy.name = this.name;
|
||||
copy.conditions.copyFrom(this.conditions);
|
||||
copy.simulationListeners = (ArrayList<String>) this.simulationListeners.clone();
|
||||
copy.simulatorClass = this.simulatorClass;
|
||||
copy.calculatorClass = this.calculatorClass;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
package net.sf.openrocket.document.events;
|
||||
|
||||
import javax.swing.event.ChangeEvent;
|
||||
|
||||
public class DocumentChangeEvent extends ChangeEvent {
|
||||
|
||||
public DocumentChangeEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package net.sf.openrocket.document.events;
|
||||
|
||||
public interface DocumentChangeListener {
|
||||
|
||||
public void documentChanged(DocumentChangeEvent event);
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package net.sf.openrocket.document.events;
|
||||
|
||||
|
||||
public class SimulationChangeEvent extends DocumentChangeEvent {
|
||||
|
||||
public SimulationChangeEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
@ -181,7 +181,7 @@ public class MotorConfigurationModel implements ComboBoxModel, ChangeListener {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return rocket.getMotorConfigurationDescription(id);
|
||||
return rocket.getMotorConfigurationNameOrDescription(id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +219,7 @@ public class MotorConfigurationModel implements ComboBoxModel, ChangeListener {
|
||||
columnList.add(new Column("Name") {
|
||||
@Override
|
||||
public Object getValueAt(int row) {
|
||||
return rocket.getMotorConfigurationDescription(ids[row]);
|
||||
return rocket.getMotorConfigurationNameOrDescription(ids[row]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -16,8 +16,10 @@ 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.DescriptionArea;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.EngineBlock;
|
||||
import net.sf.openrocket.rocketcomponent.RingComponent;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
@ -142,8 +144,17 @@ public class RingComponentConfig extends RocketComponentConfig {
|
||||
|
||||
|
||||
//// Material
|
||||
panel.add(materialPanel(new JPanel(new MigLayout()), Material.Type.BULK),
|
||||
"cell 4 0, gapleft paragraph, aligny 0%, spany");
|
||||
JPanel sub = materialPanel(new JPanel(new MigLayout()), Material.Type.BULK);
|
||||
|
||||
if (component instanceof EngineBlock) {
|
||||
DescriptionArea desc = new DescriptionArea(6,-1);
|
||||
desc.setText("<html>An engine block stops the motor from moving forwards in " +
|
||||
"the motor mount tube.<br><br>In order to add a motor, create a body tube " +
|
||||
"or inner tube and mark it as a motor mount in the <em>Motor</em> " +
|
||||
"tab.");
|
||||
sub.add(desc, "growx");
|
||||
}
|
||||
panel.add(sub,"cell 4 0, gapleft paragraph, aligny 0%, spany");
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public class BugDialog extends JDialog {
|
||||
sb.append('\n');
|
||||
sb.append("---------- Included system information ----------\n");
|
||||
sb.append("OpenRocket version: " + Prefs.getVersion() + "\n");
|
||||
sb.append("OpenRocket source: " + Prefs.getBuildSource() + "\n");
|
||||
sb.append("OpenRocket location: " + JarUtil.getCurrentJarFile() + "\n");
|
||||
sb.append("System properties:\n");
|
||||
|
||||
|
@ -34,6 +34,7 @@ import javax.swing.JSeparator;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
@ -96,6 +97,10 @@ public class BasicFrame extends JFrame {
|
||||
};
|
||||
|
||||
|
||||
|
||||
public static final int COMPONENT_TAB = 0;
|
||||
public static final int SIMULATION_TAB = 1;
|
||||
|
||||
|
||||
/**
|
||||
* List of currently open frames. When the list goes empty
|
||||
@ -118,10 +123,13 @@ public class BasicFrame extends JFrame {
|
||||
private final OpenRocketDocument document;
|
||||
private final Rocket rocket;
|
||||
|
||||
private JTabbedPane tabbedPane;
|
||||
private RocketPanel rocketpanel;
|
||||
private ComponentTree tree = null;
|
||||
|
||||
private final DocumentSelectionModel selectionModel;
|
||||
private final TreeSelectionModel componentSelectionModel;
|
||||
// private final ListSelectionModel simulationSelectionModel; ...
|
||||
private final ListSelectionModel simulationSelectionModel;
|
||||
|
||||
/** Actions available for rocket modifications */
|
||||
private final RocketActions actions;
|
||||
@ -150,11 +158,21 @@ public class BasicFrame extends JFrame {
|
||||
});
|
||||
|
||||
|
||||
// Create the selection model that will be used
|
||||
// Create the component tree selection model that will be used
|
||||
componentSelectionModel = new DefaultTreeSelectionModel();
|
||||
componentSelectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
|
||||
actions = new RocketActions(document, componentSelectionModel, this);
|
||||
// Obtain the simulation selection model that will be used
|
||||
SimulationPanel simulationPanel = new SimulationPanel(document);
|
||||
simulationSelectionModel = simulationPanel.getSimulationListSelectionModel();
|
||||
|
||||
// Combine into a DocumentSelectionModel
|
||||
selectionModel = new DocumentSelectionModel(document);
|
||||
selectionModel.attachComponentTreeSelectionModel(componentSelectionModel);
|
||||
selectionModel.attachSimulationListSelectionModel(simulationSelectionModel);
|
||||
|
||||
|
||||
actions = new RocketActions(document, selectionModel, this);
|
||||
|
||||
|
||||
// The main vertical split pane
|
||||
@ -164,11 +182,11 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
|
||||
// The top tabbed pane
|
||||
JTabbedPane tabbed = new JTabbedPane();
|
||||
tabbed.addTab("Rocket design", null, designTab());
|
||||
tabbed.addTab("Flight simulations", null, simulationsTab());
|
||||
tabbedPane = new JTabbedPane();
|
||||
tabbedPane.addTab("Rocket design", null, designTab());
|
||||
tabbedPane.addTab("Flight simulations", null, simulationPanel);
|
||||
|
||||
vertical.setTopComponent(tabbed);
|
||||
vertical.setTopComponent(tabbedPane);
|
||||
|
||||
|
||||
|
||||
@ -334,15 +352,6 @@ public class BasicFrame extends JFrame {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct the "Flight simulations" tab.
|
||||
* @return
|
||||
*/
|
||||
private JComponent simulationsTab() {
|
||||
return new SimulationPanel(document);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates the menu for the window.
|
||||
@ -553,6 +562,16 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Select the tab on the main pane.
|
||||
*
|
||||
* @param tab one of {@link #COMPONENT_TAB} or {@link #SIMULATION_TAB}.
|
||||
*/
|
||||
public void selectTab(int tab) {
|
||||
tabbedPane.setSelectedIndex(tab);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void openAction() {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
|
7
src/net/sf/openrocket/gui/main/ClipboardListener.java
Normal file
7
src/net/sf/openrocket/gui/main/ClipboardListener.java
Normal file
@ -0,0 +1,7 @@
|
||||
package net.sf.openrocket.gui.main;
|
||||
|
||||
public interface ClipboardListener {
|
||||
|
||||
public void clipboardChanged();
|
||||
|
||||
}
|
@ -55,6 +55,19 @@ public class DocumentSelectionModel {
|
||||
public Simulation[] getSelectedSimulations() {
|
||||
return Arrays.copyOf(simulationSelection, simulationSelection.length);
|
||||
}
|
||||
|
||||
public void setSelectedSimulations(Simulation[] sims) {
|
||||
simulationSelection = sims;
|
||||
clearComponentSelection();
|
||||
|
||||
simulationListSelectionModel.clearSelection();
|
||||
for (Simulation s: sims) {
|
||||
int index = document.getSimulationIndex(s);
|
||||
if (index >= 0) {
|
||||
simulationListSelectionModel.addSelectionInterval(index, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the currently selected rocket component. Returns <code>null</code>
|
||||
@ -65,6 +78,14 @@ public class DocumentSelectionModel {
|
||||
public RocketComponent getSelectedComponent() {
|
||||
return componentSelection;
|
||||
}
|
||||
|
||||
public void setSelectedComponent(RocketComponent component) {
|
||||
componentSelection = component;
|
||||
clearSimulationSelection();
|
||||
|
||||
TreePath path = ComponentTreeModel.makeTreePath(component);
|
||||
componentTreeSelectionModel.setSelectionPath(path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,11 +1,17 @@
|
||||
package net.sf.openrocket.gui.main;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
||||
public class OpenRocketClipboard {
|
||||
public final class OpenRocketClipboard {
|
||||
|
||||
private static Object clipboard = null;
|
||||
private static RocketComponent clipboardComponent = null;
|
||||
private static Simulation[] clipboardSimulations = null;
|
||||
|
||||
private static List<ClipboardListener> listeners = new ArrayList<ClipboardListener>();
|
||||
|
||||
private OpenRocketClipboard() {
|
||||
// Disallow instantiation
|
||||
@ -14,22 +20,51 @@ public class OpenRocketClipboard {
|
||||
|
||||
/**
|
||||
* Return the <code>RocketComponent</code> contained in the clipboard, or
|
||||
* <code>null</code>.
|
||||
* <code>null</code>. The component is returned verbatim, and must be copied
|
||||
* before attaching to any rocket design!
|
||||
*
|
||||
* @return the rocket component contained in the clipboard, or <code>null</code>
|
||||
* if the clipboard does not currently contain a rocket component.
|
||||
*/
|
||||
public static RocketComponent getComponent() {
|
||||
if (clipboard instanceof RocketComponent) {
|
||||
return (RocketComponent) clipboard;
|
||||
public static RocketComponent getClipboardComponent() {
|
||||
return clipboardComponent;
|
||||
}
|
||||
|
||||
|
||||
public static void setClipboard(RocketComponent component) {
|
||||
clipboardComponent = component;
|
||||
clipboardSimulations = null;
|
||||
fireClipboardChanged();
|
||||
}
|
||||
|
||||
|
||||
public static Simulation[] getClipboardSimulations() {
|
||||
if (clipboardSimulations == null || clipboardSimulations.length == 0)
|
||||
return null;
|
||||
return clipboardSimulations.clone();
|
||||
}
|
||||
|
||||
public static void setClipboard(Simulation[] simulations) {
|
||||
clipboardSimulations = simulations.clone();
|
||||
clipboardComponent = null;
|
||||
fireClipboardChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void addClipboardListener(ClipboardListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public static void removeClipboardListener(ClipboardListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
private static void fireClipboardChanged() {
|
||||
ClipboardListener[] array = listeners.toArray(new ClipboardListener[0]);
|
||||
for (ClipboardListener l: array) {
|
||||
l.clipboardChanged();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Simulation[] getSimulations() {
|
||||
return null; // TODO
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -4,18 +4,18 @@ package net.sf.openrocket.gui.main;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
|
||||
@ -24,6 +24,7 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Stage;
|
||||
import net.sf.openrocket.util.Icons;
|
||||
import net.sf.openrocket.util.Pair;
|
||||
import net.sf.openrocket.util.Prefs;
|
||||
|
||||
|
||||
|
||||
@ -35,15 +36,21 @@ import net.sf.openrocket.util.Pair;
|
||||
*/
|
||||
public class RocketActions {
|
||||
|
||||
private static RocketComponent clipboard = null;
|
||||
private static List<RocketAction> clipboardListeners = new ArrayList<RocketAction>();
|
||||
|
||||
public static final KeyStroke CUT_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_X,
|
||||
ActionEvent.CTRL_MASK);
|
||||
public static final KeyStroke COPY_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_C,
|
||||
ActionEvent.CTRL_MASK);
|
||||
public static final KeyStroke PASTE_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_V,
|
||||
ActionEvent.CTRL_MASK);
|
||||
|
||||
private final OpenRocketDocument document;
|
||||
private final Rocket rocket;
|
||||
private final JFrame parentFrame;
|
||||
private final TreeSelectionModel selectionModel;
|
||||
private final BasicFrame parentFrame;
|
||||
private final DocumentSelectionModel selectionModel;
|
||||
|
||||
|
||||
private final RocketAction deleteComponentAction;
|
||||
private final RocketAction deleteSimulationAction;
|
||||
private final RocketAction deleteAction;
|
||||
private final RocketAction cutAction;
|
||||
private final RocketAction copyAction;
|
||||
@ -54,8 +61,8 @@ public class RocketActions {
|
||||
private final RocketAction moveDownAction;
|
||||
|
||||
|
||||
public RocketActions(OpenRocketDocument document, TreeSelectionModel selectionModel,
|
||||
JFrame parentFrame) {
|
||||
public RocketActions(OpenRocketDocument document, DocumentSelectionModel selectionModel,
|
||||
BasicFrame parentFrame) {
|
||||
this.document = document;
|
||||
this.rocket = document.getRocket();
|
||||
this.selectionModel = selectionModel;
|
||||
@ -63,6 +70,8 @@ public class RocketActions {
|
||||
|
||||
// Add action also to updateActions()
|
||||
this.deleteAction = new DeleteAction();
|
||||
this.deleteComponentAction = new DeleteComponentAction();
|
||||
this.deleteSimulationAction = new DeleteSimulationAction();
|
||||
this.cutAction = new CutAction();
|
||||
this.copyAction = new CopyAction();
|
||||
this.pasteAction = new PasteAction();
|
||||
@ -71,13 +80,14 @@ public class RocketActions {
|
||||
this.moveUpAction = new MoveUpAction();
|
||||
this.moveDownAction = new MoveDownAction();
|
||||
|
||||
OpenRocketClipboard.addClipboardListener(this.pasteAction);
|
||||
updateActions();
|
||||
|
||||
// Update all actions when tree selection or rocket changes
|
||||
|
||||
selectionModel.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
selectionModel.addDocumentSelectionListener(new DocumentSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
public void valueChanged(int changeType) {
|
||||
updateActions();
|
||||
}
|
||||
});
|
||||
@ -93,28 +103,26 @@ public class RocketActions {
|
||||
* Update the state of all of the actions.
|
||||
*/
|
||||
private void updateActions() {
|
||||
deleteAction.update();
|
||||
cutAction.update();
|
||||
copyAction.update();
|
||||
pasteAction.update();
|
||||
editAction.update();
|
||||
newStageAction.update();
|
||||
moveUpAction.update();
|
||||
moveDownAction.update();
|
||||
deleteAction.clipboardChanged();
|
||||
cutAction.clipboardChanged();
|
||||
copyAction.clipboardChanged();
|
||||
pasteAction.clipboardChanged();
|
||||
editAction.clipboardChanged();
|
||||
newStageAction.clipboardChanged();
|
||||
moveUpAction.clipboardChanged();
|
||||
moveDownAction.clipboardChanged();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the state of all actions that depend on the clipboard.
|
||||
*/
|
||||
private void updateClipboardActions() {
|
||||
RocketAction[] array = clipboardListeners.toArray(new RocketAction[0]);
|
||||
for (RocketAction a: array) {
|
||||
a.update();
|
||||
}
|
||||
|
||||
|
||||
public Action getDeleteComponentAction() {
|
||||
return deleteAction;
|
||||
}
|
||||
|
||||
|
||||
public Action getDeleteSimulationAction() {
|
||||
return deleteAction;
|
||||
}
|
||||
|
||||
public Action getDeleteAction() {
|
||||
return deleteAction;
|
||||
@ -152,30 +160,6 @@ public class RocketActions {
|
||||
|
||||
//////// Helper methods for the actions
|
||||
|
||||
/**
|
||||
* Return the currently selected rocket component, or null if none selected.
|
||||
*
|
||||
* @return the currently selected component.
|
||||
*/
|
||||
private RocketComponent getSelectedComponent() {
|
||||
RocketComponent c = null;
|
||||
TreePath p = selectionModel.getSelectionPath();
|
||||
if (p != null)
|
||||
c = (RocketComponent) p.getLastPathComponent();
|
||||
|
||||
if (c != null && c.getRocket() != rocket) {
|
||||
throw new IllegalStateException("Selection not same as document rocket, "
|
||||
+ "report bug!");
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private void setSelectedComponent(RocketComponent component) {
|
||||
TreePath path = ComponentTreeModel.makeTreePath(component);
|
||||
selectionModel.setSelectionPath(path);
|
||||
}
|
||||
|
||||
|
||||
private boolean isDeletable(RocketComponent c) {
|
||||
// Sanity check
|
||||
if (c == null || c.getParent() == null)
|
||||
@ -195,7 +179,8 @@ public class RocketActions {
|
||||
|
||||
private void delete(RocketComponent c) {
|
||||
if (!isDeletable(c)) {
|
||||
throw new IllegalArgumentException("Report bug! Component " + c + " not deletable.");
|
||||
throw new IllegalArgumentException("Report bug! Component " + c +
|
||||
" not deletable.");
|
||||
}
|
||||
|
||||
RocketComponent parent = c.getParent();
|
||||
@ -211,6 +196,42 @@ public class RocketActions {
|
||||
}
|
||||
|
||||
|
||||
private boolean isSimulationSelected() {
|
||||
Simulation[] selection = selectionModel.getSelectedSimulations();
|
||||
return (selection != null && selection.length > 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean verifyDeleteSimulation() {
|
||||
boolean verify = Prefs.NODE.getBoolean(Prefs.CONFIRM_DELETE_SIMULATION, true);
|
||||
if (verify) {
|
||||
JPanel panel = new JPanel(new MigLayout());
|
||||
JCheckBox dontAsk = new JCheckBox("Do not ask me again");
|
||||
panel.add(dontAsk,"wrap");
|
||||
panel.add(new ResizeLabel("You can change the default operation in the " +
|
||||
"preferences.",-2));
|
||||
|
||||
int ret = JOptionPane.showConfirmDialog(
|
||||
parentFrame,
|
||||
new Object[] {
|
||||
"Delete the selected simulations?",
|
||||
"<html><i>This operation cannot be undone.</i>",
|
||||
"",
|
||||
panel },
|
||||
"Delete simulations",
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
if (ret != JOptionPane.OK_OPTION)
|
||||
return false;
|
||||
|
||||
if (dontAsk.isSelected()) {
|
||||
Prefs.NODE.putBoolean(Prefs.CONFIRM_DELETE_SIMULATION, false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -218,10 +239,11 @@ public class RocketActions {
|
||||
* should be pasted. Returns null if the clipboard is empty or if the
|
||||
* clipboard cannot be pasted to the current selection.
|
||||
*
|
||||
* @param clipboard the component on the clipboard.
|
||||
* @return a Pair with both components defined, or null.
|
||||
*/
|
||||
private Pair<RocketComponent, Integer> getPastePosition() {
|
||||
RocketComponent selected = getSelectedComponent();
|
||||
private Pair<RocketComponent, Integer> getPastePosition(RocketComponent clipboard) {
|
||||
RocketComponent selected = selectionModel.getSelectedComponent();
|
||||
if (selected == null)
|
||||
return null;
|
||||
|
||||
@ -246,39 +268,105 @@ public class RocketActions {
|
||||
|
||||
/////// Action classes
|
||||
|
||||
private abstract class RocketAction extends AbstractAction {
|
||||
public abstract void update();
|
||||
private abstract class RocketAction extends AbstractAction implements ClipboardListener {
|
||||
public abstract void clipboardChanged();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Action that deletes the selected component.
|
||||
*/
|
||||
private class DeleteAction extends RocketAction {
|
||||
public DeleteAction() {
|
||||
private class DeleteComponentAction extends RocketAction {
|
||||
public DeleteComponentAction() {
|
||||
this.putValue(NAME, "Delete");
|
||||
this.putValue(SHORT_DESCRIPTION, "Delete the selected component and subcomponents.");
|
||||
this.putValue(SHORT_DESCRIPTION, "Delete the selected component.");
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
||||
// this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
|
||||
update();
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RocketComponent c = getSelectedComponent();
|
||||
if (!isDeletable(c))
|
||||
return;
|
||||
RocketComponent c = selectionModel.getSelectedComponent();
|
||||
|
||||
ComponentConfigDialog.hideDialog();
|
||||
if (isDeletable(c)) {
|
||||
ComponentConfigDialog.hideDialog();
|
||||
|
||||
document.addUndoPosition("Delete " + c.getComponentName());
|
||||
delete(c);
|
||||
document.addUndoPosition("Delete " + c.getComponentName());
|
||||
delete(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.setEnabled(isDeletable(getSelectedComponent()));
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(isDeletable(selectionModel.getSelectedComponent()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Action that deletes the selected component.
|
||||
*/
|
||||
private class DeleteSimulationAction extends RocketAction {
|
||||
public DeleteSimulationAction() {
|
||||
this.putValue(NAME, "Delete");
|
||||
this.putValue(SHORT_DESCRIPTION, "Delete the selected simulation.");
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
|
||||
// this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||
if (sims.length > 0) {
|
||||
if (verifyDeleteSimulation()) {
|
||||
for (Simulation s: sims) {
|
||||
document.removeSimulation(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(isSimulationSelected());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Action that deletes the selected component.
|
||||
*/
|
||||
private class DeleteAction extends RocketAction {
|
||||
public DeleteAction() {
|
||||
this.putValue(NAME, "Delete");
|
||||
this.putValue(SHORT_DESCRIPTION, "Delete the selected component or simulation.");
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (isSimulationSelected()) {
|
||||
deleteSimulationAction.actionPerformed(e);
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
} else {
|
||||
deleteComponentAction.actionPerformed(e);
|
||||
parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(isDeletable(selectionModel.getSelectedComponent()) ||
|
||||
isSimulationSelected());
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,32 +379,44 @@ public class RocketActions {
|
||||
public CutAction() {
|
||||
this.putValue(NAME, "Cut");
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_T);
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X,
|
||||
ActionEvent.CTRL_MASK));
|
||||
this.putValue(SHORT_DESCRIPTION, "Cut this component (and subcomponents) to "
|
||||
this.putValue(ACCELERATOR_KEY, CUT_KEY_STROKE);
|
||||
this.putValue(SHORT_DESCRIPTION, "Cut this component or simulation to "
|
||||
+ "the clipboard and remove from this design");
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_CUT);
|
||||
update();
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RocketComponent c = getSelectedComponent();
|
||||
if (!isDeletable(c) || !isCopyable(c))
|
||||
return;
|
||||
RocketComponent c = selectionModel.getSelectedComponent();
|
||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||
|
||||
ComponentConfigDialog.hideDialog();
|
||||
if (isDeletable(c) && isCopyable(c)) {
|
||||
ComponentConfigDialog.hideDialog();
|
||||
|
||||
document.addUndoPosition("Cut " + c.getComponentName());
|
||||
OpenRocketClipboard.setClipboard(c.copy());
|
||||
delete(c);
|
||||
parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
|
||||
} else if (isSimulationSelected()) {
|
||||
|
||||
document.addUndoPosition("Cut " + c.getComponentName());
|
||||
clipboard = c.copy();
|
||||
delete(c);
|
||||
updateClipboardActions();
|
||||
Simulation[] simsCopy = new Simulation[sims.length];
|
||||
for (int i=0; i < sims.length; i++) {
|
||||
simsCopy[i] = sims[i].copy();
|
||||
}
|
||||
OpenRocketClipboard.setClipboard(simsCopy);
|
||||
|
||||
for (Simulation s: sims) {
|
||||
document.removeSimulation(s);
|
||||
}
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
RocketComponent c = getSelectedComponent();
|
||||
this.setEnabled(isDeletable(c) && isCopyable(c));
|
||||
public void clipboardChanged() {
|
||||
RocketComponent c = selectionModel.getSelectedComponent();
|
||||
this.setEnabled((isDeletable(c) && isCopyable(c)) || isSimulationSelected());
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,27 +429,36 @@ public class RocketActions {
|
||||
public CopyAction() {
|
||||
this.putValue(NAME, "Copy");
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_C);
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C,
|
||||
ActionEvent.CTRL_MASK));
|
||||
this.putValue(ACCELERATOR_KEY, COPY_KEY_STROKE);
|
||||
this.putValue(SHORT_DESCRIPTION, "Copy this component (and subcomponents) to "
|
||||
+ "the clipboard.");
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_COPY);
|
||||
update();
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RocketComponent c = getSelectedComponent();
|
||||
if (!isCopyable(c))
|
||||
return;
|
||||
RocketComponent c = selectionModel.getSelectedComponent();
|
||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||
|
||||
clipboard = c.copy();
|
||||
updateClipboardActions();
|
||||
if (isCopyable(c)) {
|
||||
OpenRocketClipboard.setClipboard(c.copy());
|
||||
parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
|
||||
} else if (sims.length >= 0) {
|
||||
|
||||
Simulation[] simsCopy = new Simulation[sims.length];
|
||||
for (int i=0; i < sims.length; i++) {
|
||||
simsCopy[i] = sims[i].copy();
|
||||
}
|
||||
OpenRocketClipboard.setClipboard(simsCopy);
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.setEnabled(isCopyable(getSelectedComponent()));
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(isCopyable(selectionModel.getSelectedComponent()) ||
|
||||
isSimulationSelected());
|
||||
}
|
||||
|
||||
}
|
||||
@ -365,34 +474,53 @@ public class RocketActions {
|
||||
public PasteAction() {
|
||||
this.putValue(NAME, "Paste");
|
||||
this.putValue(MNEMONIC_KEY, KeyEvent.VK_P);
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_V,
|
||||
ActionEvent.CTRL_MASK));
|
||||
this.putValue(SHORT_DESCRIPTION, "Paste the component (and subcomponents) on "
|
||||
this.putValue(ACCELERATOR_KEY, PASTE_KEY_STROKE);
|
||||
this.putValue(SHORT_DESCRIPTION, "Paste the component or simulation on "
|
||||
+ "the clipboard to the design.");
|
||||
this.putValue(SMALL_ICON, Icons.EDIT_PASTE);
|
||||
update();
|
||||
|
||||
// Listen to when the clipboard changes
|
||||
clipboardListeners.add(this);
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Pair<RocketComponent, Integer> position = getPastePosition();
|
||||
if (position == null)
|
||||
return;
|
||||
RocketComponent clipboard = OpenRocketClipboard.getClipboardComponent();
|
||||
Simulation[] sims = OpenRocketClipboard.getClipboardSimulations();
|
||||
|
||||
Pair<RocketComponent, Integer> position = getPastePosition(clipboard);
|
||||
if (position != null) {
|
||||
ComponentConfigDialog.hideDialog();
|
||||
|
||||
RocketComponent pasted = clipboard.copy();
|
||||
document.addUndoPosition("Paste " + pasted.getComponentName());
|
||||
position.getU().addChild(pasted, position.getV());
|
||||
selectionModel.setSelectedComponent(pasted);
|
||||
|
||||
parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
|
||||
|
||||
} else if (sims != null) {
|
||||
|
||||
ArrayList<Simulation> copySims = new ArrayList<Simulation>();
|
||||
|
||||
ComponentConfigDialog.hideDialog();
|
||||
|
||||
RocketComponent pasted = clipboard.copy();
|
||||
document.addUndoPosition("Paste " + pasted.getComponentName());
|
||||
position.getU().addChild(pasted, position.getV());
|
||||
setSelectedComponent(pasted);
|
||||
for (Simulation s: sims) {
|
||||
Simulation copy = s.duplicateSimulation(rocket);
|
||||
String name = copy.getName();
|
||||
if (name.matches(OpenRocketDocument.SIMULATION_NAME_PREFIX + "[0-9]+ *")) {
|
||||
copy.setName(document.getNextSimulationName());
|
||||
}
|
||||
document.addSimulation(copy);
|
||||
copySims.add(copy);
|
||||
}
|
||||
selectionModel.setSelectedSimulations(copySims.toArray(new Simulation[0]));
|
||||
|
||||
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.setEnabled(getPastePosition() != null);
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(
|
||||
(getPastePosition(OpenRocketClipboard.getClipboardComponent()) != null) ||
|
||||
(OpenRocketClipboard.getClipboardSimulations() != null));
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,12 +536,12 @@ public class RocketActions {
|
||||
public EditAction() {
|
||||
this.putValue(NAME, "Edit");
|
||||
this.putValue(SHORT_DESCRIPTION, "Edit the selected component.");
|
||||
update();
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RocketComponent c = getSelectedComponent();
|
||||
RocketComponent c = selectionModel.getSelectedComponent();
|
||||
if (c == null)
|
||||
return;
|
||||
|
||||
@ -421,8 +549,8 @@ public class RocketActions {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.setEnabled(getSelectedComponent() != null);
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(selectionModel.getSelectedComponent() != null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,7 +567,7 @@ public class RocketActions {
|
||||
public NewStageAction() {
|
||||
this.putValue(NAME, "New stage");
|
||||
this.putValue(SHORT_DESCRIPTION, "Add a new stage to the rocket design.");
|
||||
update();
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -452,13 +580,13 @@ public class RocketActions {
|
||||
document.addUndoPosition("Add stage");
|
||||
rocket.addChild(stage);
|
||||
rocket.getDefaultConfiguration().setAllStages();
|
||||
setSelectedComponent(stage);
|
||||
selectionModel.setSelectedComponent(stage);
|
||||
ComponentConfigDialog.showDialog(parentFrame, document, stage);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(true);
|
||||
}
|
||||
}
|
||||
@ -473,12 +601,12 @@ public class RocketActions {
|
||||
public MoveUpAction() {
|
||||
this.putValue(NAME, "Move up");
|
||||
this.putValue(SHORT_DESCRIPTION, "Move this component upwards.");
|
||||
update();
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RocketComponent selected = getSelectedComponent();
|
||||
RocketComponent selected = selectionModel.getSelectedComponent();
|
||||
if (!canMove(selected))
|
||||
return;
|
||||
|
||||
@ -487,12 +615,12 @@ public class RocketActions {
|
||||
RocketComponent parent = selected.getParent();
|
||||
document.addUndoPosition("Move "+selected.getComponentName());
|
||||
parent.moveChild(selected, parent.getChildPosition(selected)-1);
|
||||
setSelectedComponent(selected);
|
||||
selectionModel.setSelectedComponent(selected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.setEnabled(canMove(getSelectedComponent()));
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(canMove(selectionModel.getSelectedComponent()));
|
||||
}
|
||||
|
||||
private boolean canMove(RocketComponent c) {
|
||||
@ -514,12 +642,12 @@ public class RocketActions {
|
||||
public MoveDownAction() {
|
||||
this.putValue(NAME, "Move down");
|
||||
this.putValue(SHORT_DESCRIPTION, "Move this component downwards.");
|
||||
update();
|
||||
clipboardChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
RocketComponent selected = getSelectedComponent();
|
||||
RocketComponent selected = selectionModel.getSelectedComponent();
|
||||
if (!canMove(selected))
|
||||
return;
|
||||
|
||||
@ -528,12 +656,12 @@ public class RocketActions {
|
||||
RocketComponent parent = selected.getParent();
|
||||
document.addUndoPosition("Move "+selected.getComponentName());
|
||||
parent.moveChild(selected, parent.getChildPosition(selected)+1);
|
||||
setSelectedComponent(selected);
|
||||
selectionModel.setSelectedComponent(selected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.setEnabled(canMove(getSelectedComponent()));
|
||||
public void clipboardChanged() {
|
||||
this.setEnabled(canMove(selectionModel.getSelectedComponent()));
|
||||
}
|
||||
|
||||
private boolean canMove(RocketComponent c) {
|
||||
|
@ -5,6 +5,7 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Arrays;
|
||||
@ -17,6 +18,8 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
@ -25,6 +28,9 @@ import net.sf.openrocket.aerodynamics.Warning;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.document.events.DocumentChangeEvent;
|
||||
import net.sf.openrocket.document.events.DocumentChangeListener;
|
||||
import net.sf.openrocket.document.events.SimulationChangeEvent;
|
||||
import net.sf.openrocket.gui.adaptors.Column;
|
||||
import net.sf.openrocket.gui.adaptors.ColumnTableModel;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
@ -43,8 +49,6 @@ public class SimulationPanel extends JPanel {
|
||||
private static final Color OK_COLOR = new Color(60,150,0);
|
||||
private static final String OK_TEXT = "\u2714"; // Heavy check mark
|
||||
|
||||
private static final String NAME_PREFIX = "Simulation ";
|
||||
|
||||
|
||||
|
||||
private final OpenRocketDocument document;
|
||||
@ -70,21 +74,8 @@ public class SimulationPanel extends JPanel {
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
// Generate unique name for the simulation
|
||||
int maxValue = 0;
|
||||
for (Simulation s: document.getSimulations()) {
|
||||
String name = s.getName();
|
||||
if (name.startsWith(NAME_PREFIX)) {
|
||||
try {
|
||||
maxValue = Math.max(maxValue,
|
||||
Integer.parseInt(name.substring(NAME_PREFIX.length())));
|
||||
} catch (NumberFormatException ignore) { }
|
||||
}
|
||||
}
|
||||
|
||||
Simulation sim = new Simulation(document.getRocket());
|
||||
sim.setName(NAME_PREFIX + (maxValue+1));
|
||||
sim.setName(document.getNextSimulationName());
|
||||
|
||||
int n = document.getSimulationCount();
|
||||
document.addSimulation(sim);
|
||||
@ -231,6 +222,7 @@ public class SimulationPanel extends JPanel {
|
||||
|
||||
// Set simulation status icon
|
||||
Simulation.Status status = document.getSimulation(row).getStatus();
|
||||
System.out.println("status=" + status);
|
||||
label.setIcon(Icons.SIMULATION_STATUS_ICON_MAP.get(status));
|
||||
|
||||
|
||||
@ -388,11 +380,22 @@ public class SimulationPanel extends JPanel {
|
||||
}
|
||||
};
|
||||
|
||||
simulationTable = new JTable(simulationTableModel);
|
||||
// Override processKeyBinding so that the JTable does not catch
|
||||
// key bindings used in menu accelerators
|
||||
simulationTable = new JTable(simulationTableModel) {
|
||||
@Override
|
||||
protected boolean processKeyBinding(KeyStroke ks,
|
||||
KeyEvent e,
|
||||
int condition,
|
||||
boolean pressed) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
simulationTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
||||
simulationTable.setDefaultRenderer(Object.class, new JLabelRenderer());
|
||||
simulationTableModel.setColumnWidths(simulationTable.getColumnModel());
|
||||
|
||||
|
||||
// Mouse listener to act on double-clicks
|
||||
simulationTable.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
@ -411,6 +414,15 @@ public class SimulationPanel extends JPanel {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.addDocumentChangeListener(new DocumentChangeListener() {
|
||||
@Override
|
||||
public void documentChanged(DocumentChangeEvent event) {
|
||||
if (!(event instanceof SimulationChangeEvent))
|
||||
return;
|
||||
simulationTableModel.fireTableDataChanged();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -431,6 +443,10 @@ public class SimulationPanel extends JPanel {
|
||||
}
|
||||
|
||||
|
||||
public ListSelectionModel getSimulationListSelectionModel() {
|
||||
return simulationTable.getSelectionModel();
|
||||
}
|
||||
|
||||
private void openDialog(final Simulation sim, int position) {
|
||||
new SimulationEditDialog(SwingUtilities.getWindowAncestor(this), sim, position)
|
||||
.setVisible(true);
|
||||
@ -441,6 +457,8 @@ public class SimulationPanel extends JPanel {
|
||||
int[] selection = simulationTable.getSelectedRows();
|
||||
simulationTableModel.fireTableDataChanged();
|
||||
for (int row: selection) {
|
||||
if (row >= simulationTableModel.getRowCount())
|
||||
break;
|
||||
simulationTable.addRowSelectionInterval(row, row);
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
|
||||
public void setSelection(RocketComponent[] selection) {
|
||||
if (selection == null) {
|
||||
selection = new RocketComponent[0];
|
||||
this.selection = new RocketComponent[0];
|
||||
} else {
|
||||
this.selection = selection;
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi
|
||||
}
|
||||
|
||||
public String getMotorConfigurationDescription() {
|
||||
return rocket.getMotorConfigurationDescription(motorConfiguration);
|
||||
return rocket.getMotorConfigurationNameOrDescription(motorConfiguration);
|
||||
}
|
||||
|
||||
|
||||
|
@ -534,6 +534,42 @@ public class Rocket extends RocketComponent {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether <code>id</code> is a valid motor configuration ID.
|
||||
*
|
||||
* @param id the configuration ID.
|
||||
* @return whether a motor configuration with that ID exists.
|
||||
*/
|
||||
public boolean isMotorConfigurationID(String id) {
|
||||
return motorConfigurationIDs.contains(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the given motor configuration ID has motors defined for it.
|
||||
*
|
||||
* @param id the motor configuration ID (may be invalid).
|
||||
* @return whether any motors are defined for it.
|
||||
*/
|
||||
public boolean hasMotors(String id) {
|
||||
Iterator<RocketComponent> iterator = this.deepIterator();
|
||||
while (iterator.hasNext()) {
|
||||
RocketComponent c = iterator.next();
|
||||
|
||||
if (c instanceof MotorMount) {
|
||||
MotorMount mount = (MotorMount) c;
|
||||
if (!mount.isMotorMount())
|
||||
continue;
|
||||
if (mount.getMotor(id) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the user-set name of the motor configuration. If no name has been set,
|
||||
* returns an empty string (not null).
|
||||
@ -563,9 +599,24 @@ public class Rocket extends RocketComponent {
|
||||
|
||||
|
||||
/**
|
||||
* Return a description for the motor configuration. This is either the
|
||||
* name previously set by {@link #setMotorConfigurationName(String, String)} or
|
||||
* a string generated from the motor designations of the components.
|
||||
* Return either the motor configuration name (if set) or its description.
|
||||
*
|
||||
* @param id the motor configuration ID.
|
||||
* @return a textual representation of the configuration
|
||||
*/
|
||||
public String getMotorConfigurationNameOrDescription(String id) {
|
||||
String name;
|
||||
|
||||
name = motorConfigurationNames.get(id);
|
||||
if (name != null && !name.equals(""))
|
||||
return name;
|
||||
|
||||
return getMotorConfigurationDescription(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description for the motor configuration, generated from the motor
|
||||
* designations of the components.
|
||||
*
|
||||
* @param id the motor configuration ID.
|
||||
* @return a textual representation of the configuration
|
||||
@ -579,10 +630,6 @@ public class Rocket extends RocketComponent {
|
||||
throw new IllegalArgumentException("Motor configuration ID does not exist: "+id);
|
||||
}
|
||||
|
||||
name = motorConfigurationNames.get(id);
|
||||
if (name != null && !name.equals(""))
|
||||
return name;
|
||||
|
||||
// Generate the description
|
||||
|
||||
// First iterate over each stage and store the designations of each motor
|
||||
|
@ -80,9 +80,17 @@ public class SimulationConditions implements ChangeSource, Cloneable {
|
||||
return motorID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the motor configuration ID. This must be a valid motor configuration ID of
|
||||
* the rocket, otherwise the configuration is set to <code>null</code>.
|
||||
*
|
||||
* @param id the configuration to set.
|
||||
*/
|
||||
public void setMotorConfigurationID(String id) {
|
||||
if (id != null)
|
||||
id = id.intern();
|
||||
if (!rocket.isMotorConfigurationID(id))
|
||||
id = null;
|
||||
if (id == motorID)
|
||||
return;
|
||||
motorID = id;
|
||||
@ -319,14 +327,31 @@ public class SimulationConditions implements ChangeSource, Cloneable {
|
||||
|
||||
|
||||
public void copyFrom(SimulationConditions src) {
|
||||
if (this.rocket != src.rocket) {
|
||||
throw new IllegalArgumentException("Unable to copy simulation conditions of "+
|
||||
"a difference rocket");
|
||||
}
|
||||
if (this.equals(src))
|
||||
return;
|
||||
|
||||
this.motorID = src.motorID;
|
||||
if (this.rocket == src.rocket) {
|
||||
|
||||
this.motorID = src.motorID;
|
||||
|
||||
} else {
|
||||
|
||||
if (src.rocket.hasMotors(src.motorID)) {
|
||||
// Try to find a matching motor ID
|
||||
String motorDesc = src.rocket.getMotorConfigurationDescription(src.motorID);
|
||||
String matchID = null;
|
||||
|
||||
for (String id: this.rocket.getMotorConfigurationIDs()) {
|
||||
if (motorDesc.equals(this.rocket.getMotorConfigurationDescription(id))) {
|
||||
matchID = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.motorID = matchID;
|
||||
} else {
|
||||
this.motorID = null;
|
||||
}
|
||||
}
|
||||
|
||||
this.launchAltitude = src.launchAltitude;
|
||||
this.launchLatitude = src.launchLatitude;
|
||||
this.launchPressure = src.launchPressure;
|
||||
|
@ -35,21 +35,21 @@ public class Startup {
|
||||
try {
|
||||
|
||||
Class cls = Class.forName(START_CLASS);
|
||||
Method m = cls.getMethod("main", String[].class);
|
||||
Method m = cls.getMethod("main", new Class[] {String[].class});
|
||||
m.invoke(null, new Object[] { args });
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
error("Error starting main class!", "Please report a bug.");
|
||||
error(new String[] {"Error starting main class!", "Please report a bug."});
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
error("Error starting main class!", "Please report a bug.");
|
||||
error(new String[] {"Error starting main class!", "Please report a bug."});
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
error("Error starting main class!", "Please report a bug.");
|
||||
error(new String[] {"Error starting main class!", "Please report a bug."});
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
error("Error starting main class!", "Please report a bug.");
|
||||
error(new String[] {"Error starting main class!", "Please report a bug."});
|
||||
}
|
||||
|
||||
}
|
||||
@ -73,16 +73,16 @@ public class Startup {
|
||||
|
||||
if (major < REQUIRED_MAJOR_VERSION ||
|
||||
(major == REQUIRED_MAJOR_VERSION && minor < REQUIRED_MINOR_VERSION)) {
|
||||
error("Java SE version 6 is required to run OpenRocket.",
|
||||
error(new String[] {"Java SE version 6 is required to run OpenRocket.",
|
||||
"You are currently running " + jreName + " version " +
|
||||
jreVersion + " by " + jreVendor);
|
||||
jreVersion + " by " + jreVendor});
|
||||
}
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
|
||||
confirm("The Java version in use could not be detected.",
|
||||
confirm(new String[] {"The Java version in use could not be detected.",
|
||||
"OpenRocket requires at least Java SE 6.",
|
||||
"Continue anyway?");
|
||||
"Continue anyway?"});
|
||||
|
||||
}
|
||||
|
||||
@ -118,11 +118,11 @@ public class Startup {
|
||||
String jreVersion = System.getProperty("java.runtime.version", "(unknown)");
|
||||
String jreVendor = System.getProperty("java.vendor", "(unknown)");
|
||||
|
||||
confirm("OpenJDK is known to have problems running OpenRocket.",
|
||||
confirm(new String[] {"OpenJDK is known to have problems running OpenRocket.",
|
||||
" ",
|
||||
"You are currently running " + jreName + " version " +
|
||||
jreVersion + " by " + jreVendor,
|
||||
"Do you want to continue?");
|
||||
"Do you want to continue?"});
|
||||
|
||||
}
|
||||
}
|
||||
@ -135,7 +135,7 @@ public class Startup {
|
||||
*
|
||||
* @param message an array of messages to present.
|
||||
*/
|
||||
private static void error(String ... message) {
|
||||
private static void error(String[] message) {
|
||||
|
||||
System.err.println();
|
||||
System.err.println("Error starting OpenRocket:");
|
||||
@ -163,7 +163,7 @@ public class Startup {
|
||||
*
|
||||
* @param message the message Strings to show.
|
||||
*/
|
||||
private static void confirm(String ... message) {
|
||||
private static void confirm(String[] message) {
|
||||
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
|
||||
@ -171,10 +171,7 @@ public class Startup {
|
||||
JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.util;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -18,11 +19,11 @@ public class Icons {
|
||||
public static final Map<Simulation.Status, Icon> SIMULATION_STATUS_ICON_MAP;
|
||||
static {
|
||||
HashMap<Simulation.Status, Icon> map = new HashMap<Simulation.Status, Icon>();
|
||||
map.put(Simulation.Status.NOT_SIMULATED, new ImageIcon("pix/spheres/gray-16x16.png", "Not simulated"));
|
||||
map.put(Simulation.Status.UPTODATE, new ImageIcon("pix/spheres/green-16x16.png", "Up to date"));
|
||||
map.put(Simulation.Status.LOADED, new ImageIcon("pix/spheres/yellow-16x16.png", "Loaded from file"));
|
||||
map.put(Simulation.Status.OUTDATED, new ImageIcon("pix/spheres/red-16x16.png", "Out-of-date"));
|
||||
map.put(Simulation.Status.EXTERNAL, new ImageIcon("pix/spheres/blue-16x16.png", "Imported data"));
|
||||
map.put(Simulation.Status.NOT_SIMULATED, loadImageIcon("pix/spheres/gray-16x16.png", "Not simulated"));
|
||||
map.put(Simulation.Status.UPTODATE, loadImageIcon("pix/spheres/green-16x16.png", "Up to date"));
|
||||
map.put(Simulation.Status.LOADED, loadImageIcon("pix/spheres/yellow-16x16.png", "Loaded from file"));
|
||||
map.put(Simulation.Status.OUTDATED, loadImageIcon("pix/spheres/red-16x16.png", "Out-of-date"));
|
||||
map.put(Simulation.Status.EXTERNAL, loadImageIcon("pix/spheres/blue-16x16.png", "Imported data"));
|
||||
SIMULATION_STATUS_ICON_MAP = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
@ -34,23 +35,33 @@ public class Icons {
|
||||
}
|
||||
|
||||
|
||||
public static final Icon FILE_NEW = new ImageIcon(ClassLoader.getSystemResource("pix/icons/document-new.png"), "New document");
|
||||
public static final Icon FILE_OPEN = new ImageIcon(ClassLoader.getSystemResource("pix/icons/document-open.png"), "Open document");
|
||||
public static final Icon FILE_SAVE = new ImageIcon(ClassLoader.getSystemResource("pix/icons/document-save.png"), "Save document");
|
||||
public static final Icon FILE_SAVE_AS = new ImageIcon(ClassLoader.getSystemResource("pix/icons/document-save-as.png"), "Save document as");
|
||||
public static final Icon FILE_CLOSE = new ImageIcon(ClassLoader.getSystemResource("pix/icons/document-close.png"), "Close document");
|
||||
public static final Icon FILE_QUIT = new ImageIcon(ClassLoader.getSystemResource("pix/icons/application-exit.png"), "Quit OpenRocket");
|
||||
public static final Icon FILE_NEW = loadImageIcon("pix/icons/document-new.png", "New document");
|
||||
public static final Icon FILE_OPEN = loadImageIcon("pix/icons/document-open.png", "Open document");
|
||||
public static final Icon FILE_SAVE = loadImageIcon("pix/icons/document-save.png", "Save document");
|
||||
public static final Icon FILE_SAVE_AS = loadImageIcon("pix/icons/document-save-as.png", "Save document as");
|
||||
public static final Icon FILE_CLOSE = loadImageIcon("pix/icons/document-close.png", "Close document");
|
||||
public static final Icon FILE_QUIT = loadImageIcon("pix/icons/application-exit.png", "Quit OpenRocket");
|
||||
|
||||
public static final Icon EDIT_UNDO = new ImageIcon(ClassLoader.getSystemResource("pix/icons/edit-undo.png"), "Undo");
|
||||
public static final Icon EDIT_REDO = new ImageIcon(ClassLoader.getSystemResource("pix/icons/edit-redo.png"), "Redo");
|
||||
public static final Icon EDIT_CUT = new ImageIcon(ClassLoader.getSystemResource("pix/icons/edit-cut.png"), "Cut");
|
||||
public static final Icon EDIT_COPY = new ImageIcon(ClassLoader.getSystemResource("pix/icons/edit-copy.png"), "Copy");
|
||||
public static final Icon EDIT_PASTE = new ImageIcon(ClassLoader.getSystemResource("pix/icons/edit-paste.png"), "Paste");
|
||||
public static final Icon EDIT_DELETE = new ImageIcon(ClassLoader.getSystemResource("pix/icons/edit-delete.png"), "Delete");
|
||||
public static final Icon EDIT_UNDO = loadImageIcon("pix/icons/edit-undo.png", "Undo");
|
||||
public static final Icon EDIT_REDO = loadImageIcon("pix/icons/edit-redo.png", "Redo");
|
||||
public static final Icon EDIT_CUT = loadImageIcon("pix/icons/edit-cut.png", "Cut");
|
||||
public static final Icon EDIT_COPY = loadImageIcon("pix/icons/edit-copy.png", "Copy");
|
||||
public static final Icon EDIT_PASTE = loadImageIcon("pix/icons/edit-paste.png", "Paste");
|
||||
public static final Icon EDIT_DELETE = loadImageIcon("pix/icons/edit-delete.png", "Delete");
|
||||
|
||||
public static final Icon ZOOM_IN = new ImageIcon(ClassLoader.getSystemResource("pix/icons/zoom-in.png"), "Zoom in");
|
||||
public static final Icon ZOOM_OUT = new ImageIcon(ClassLoader.getSystemResource("pix/icons/zoom-out.png"), "Zoom out");
|
||||
public static final Icon ZOOM_IN = loadImageIcon("pix/icons/zoom-in.png", "Zoom in");
|
||||
public static final Icon ZOOM_OUT = loadImageIcon("pix/icons/zoom-out.png", "Zoom out");
|
||||
|
||||
public static final Icon PREFERENCES = new ImageIcon(ClassLoader.getSystemResource("pix/icons/preferences.png"), "Preferences");
|
||||
public static final Icon PREFERENCES = loadImageIcon("pix/icons/preferences.png", "Preferences");
|
||||
|
||||
|
||||
|
||||
private static ImageIcon loadImageIcon(String file, String name) {
|
||||
URL url = ClassLoader.getSystemResource(file);
|
||||
if (url == null) {
|
||||
System.err.println("Resource "+file+" not found! Ignoring...");
|
||||
return null;
|
||||
}
|
||||
return new ImageIcon(url, name);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,12 @@ import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Properties;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
@ -46,7 +50,37 @@ public class Prefs {
|
||||
|
||||
|
||||
|
||||
private static final String VERSION = "0.9.0";
|
||||
private static final String BUILD_VERSION;
|
||||
private static final String BUILD_SOURCE;
|
||||
|
||||
static {
|
||||
try {
|
||||
InputStream is = ClassLoader.getSystemResourceAsStream("build.properties");
|
||||
if (is == null) {
|
||||
throw new MissingResourceException(
|
||||
"build.properties not found, distribution built wrong",
|
||||
"build.properties", "build.version");
|
||||
}
|
||||
|
||||
Properties props = new Properties();
|
||||
props.load(is);
|
||||
is.close();
|
||||
|
||||
BUILD_VERSION = props.getProperty("build.version");
|
||||
if (BUILD_VERSION == null) {
|
||||
throw new MissingResourceException(
|
||||
"build.version not found in property file",
|
||||
"build.properties", "build.version");
|
||||
}
|
||||
|
||||
BUILD_SOURCE = props.getProperty("build.source");
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new MissingResourceException(
|
||||
"Error reading build.properties",
|
||||
"build.properties", "build.version");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final String BODY_COMPONENT_INSERT_POSITION_KEY = "BodyComponentInsertPosition";
|
||||
@ -112,7 +146,12 @@ public class Prefs {
|
||||
|
||||
|
||||
public static String getVersion() {
|
||||
return VERSION;
|
||||
return BUILD_VERSION;
|
||||
}
|
||||
|
||||
|
||||
public static String getBuildSource() {
|
||||
return BUILD_SOURCE;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user