Bug fixes and startup checks
This commit is contained in:
parent
e246eb1f17
commit
2f7baaa87c
13
ChangeLog
13
ChangeLog
@ -1,4 +1,15 @@
|
||||
2009-05-28 Sampo Niskanen
|
||||
|
||||
* Added startup check for Java 1.6 and OpenJDK
|
||||
|
||||
2009-05-28 Sampo Niskanen
|
||||
|
||||
* Fixed FixedPrecisionUnit formatting
|
||||
* Fixed saving of transitions
|
||||
* Fixed file dialog directory browsing
|
||||
* Initial shift-click selects second component from figure
|
||||
* Allow adding body components without selecting stage
|
||||
|
||||
2009-05-24 Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
|
||||
* Initial release 0.9.0
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
<!-- The main class of the application -->
|
||||
<property name="main-class" value="net.sf.openrocket.gui.main.BasicFrame"/>
|
||||
<property name="main-class" value="net.sf.openrocket.startup.Startup"/>
|
||||
|
||||
|
||||
<!-- Classpath definition -->
|
||||
|
@ -76,7 +76,7 @@
|
||||
<p>The source code for OpenRocket is available from the
|
||||
<a href="http://openrocket.svn.sourceforge.net/viewvc/openrocket/">SourceForge SVN repository</a>.
|
||||
It can be retrieved simply using the command</p>
|
||||
<pre class="quote">$ svn co https://openrocket.svn.sourceforge.net/svnroot/openrocket openrocket</pre>
|
||||
<pre class="quote">$ svn co https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk OpenRocket</pre>
|
||||
<p>The above URL may be used to connect to the repository with
|
||||
other Subversion clients as well.</p>
|
||||
|
||||
|
@ -5,10 +5,6 @@ import java.io.FileInputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.security.CodeSource;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -24,6 +20,7 @@ import javax.swing.event.EventListenerList;
|
||||
|
||||
import net.sf.openrocket.file.Loader;
|
||||
import net.sf.openrocket.util.ChangeSource;
|
||||
import net.sf.openrocket.util.JarUtil;
|
||||
|
||||
|
||||
|
||||
@ -182,17 +179,9 @@ public class Database<T extends Comparable<T>> extends AbstractSet<T> implements
|
||||
if (!dir.endsWith("/")) {
|
||||
dir += "/";
|
||||
}
|
||||
|
||||
// Find the jar file this class is contained in and open it
|
||||
URL jarUrl = null;
|
||||
CodeSource codeSource = Database.class.getProtectionDomain().getCodeSource();
|
||||
if (codeSource != null)
|
||||
jarUrl = codeSource.getLocation();
|
||||
|
||||
if (jarUrl == null) {
|
||||
throw new IOException("Could not find containing JAR file.");
|
||||
}
|
||||
File file = urlToFile(jarUrl);
|
||||
// Find and open the jar file this class is contained in
|
||||
File file = JarUtil.getCurrentJarFile();
|
||||
JarFile jarFile = new JarFile(file);
|
||||
|
||||
try {
|
||||
@ -219,22 +208,6 @@ public class Database<T extends Comparable<T>> extends AbstractSet<T> implements
|
||||
}
|
||||
|
||||
|
||||
static File urlToFile(URL url) {
|
||||
URI uri;
|
||||
try {
|
||||
uri = url.toURI();
|
||||
} catch (URISyntaxException e) {
|
||||
try {
|
||||
uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(),
|
||||
url.getPath(), url.getQuery(), url.getRef());
|
||||
} catch (URISyntaxException e1) {
|
||||
throw new IllegalArgumentException("Broken URL: " + url);
|
||||
}
|
||||
}
|
||||
return new File(uri);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void load(File file) throws IOException {
|
||||
if (loader == null) {
|
||||
|
@ -33,7 +33,7 @@ public class TransitionSaver extends SymmetricComponentSaver {
|
||||
|
||||
|
||||
Transition.Shape shape = trans.getType();
|
||||
elements.add("<shape>" + shape.getName().toLowerCase() + "</shape>");
|
||||
elements.add("<shape>" + shape.name().toLowerCase() + "</shape>");
|
||||
if (shape.isClippable()) {
|
||||
elements.add("<shapeclipped>" + trans.isClipped() + "</shapeclipped>");
|
||||
}
|
||||
|
@ -44,6 +44,10 @@ import net.sf.openrocket.gui.adaptors.Column;
|
||||
import net.sf.openrocket.gui.adaptors.ColumnTableModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.MotorConfigurationModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.StageSelector;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.gui.scalefigure.RocketPanel;
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
|
@ -18,6 +18,7 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.unit.Unit;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.GUIUtil;
|
||||
|
@ -20,7 +20,7 @@ import javax.swing.event.ChangeListener;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.database.Database;
|
||||
import net.sf.openrocket.database.Databases;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
@ -30,8 +30,8 @@ import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.TextFieldListener;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
import net.sf.openrocket.rocketcomponent.Motor;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.sf.openrocket.gui;
|
||||
package net.sf.openrocket.gui.components;
|
||||
|
||||
import javax.swing.BoundedRangeModel;
|
||||
import javax.swing.JSlider;
|
@ -1,4 +1,4 @@
|
||||
package net.sf.openrocket.gui;
|
||||
package net.sf.openrocket.gui.components;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
@ -1,4 +1,4 @@
|
||||
package net.sf.openrocket.gui;
|
||||
package net.sf.openrocket.gui.components;
|
||||
|
||||
import java.awt.Font;
|
||||
import javax.swing.JLabel;
|
@ -1,4 +1,4 @@
|
||||
package net.sf.openrocket.gui;
|
||||
package net.sf.openrocket.gui.components;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
51
src/net/sf/openrocket/gui/components/URLLabel.java
Normal file
51
src/net/sf/openrocket/gui/components/URLLabel.java
Normal file
@ -0,0 +1,51 @@
|
||||
package net.sf.openrocket.gui.components;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
* A label of a URL that is clickable. Clicking the URL will launch the URL in
|
||||
* the default browser if the Desktop class is supported.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class URLLabel extends JLabel {
|
||||
|
||||
private final String url;
|
||||
|
||||
public URLLabel(String urlLabel) {
|
||||
super();
|
||||
|
||||
this.url = urlLabel;
|
||||
|
||||
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
|
||||
setText("<html><a href=\"" + url + "\">" + url + "</a>");
|
||||
|
||||
this.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
Desktop d = Desktop.getDesktop();
|
||||
try {
|
||||
d.browse(new URI(url));
|
||||
} catch (URISyntaxException e1) {
|
||||
throw new RuntimeException("BUG: Illegal URL: " + url, e1);
|
||||
} catch (IOException e1) {
|
||||
System.err.println("Unable to launch browser:");
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
setText(url);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.sf.openrocket.gui;
|
||||
package net.sf.openrocket.gui.components;
|
||||
|
||||
|
||||
import java.awt.Color;
|
@ -7,11 +7,11 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
@ -14,12 +14,12 @@ import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.IntegerModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
|
||||
|
@ -17,13 +17,13 @@ import javax.swing.SwingConstants;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.IntegerModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.gui.scalefigure.FinPointFigure;
|
||||
import net.sf.openrocket.gui.scalefigure.ScaleScrollPane;
|
||||
import net.sf.openrocket.gui.scalefigure.ScaleSelector;
|
||||
|
@ -26,11 +26,11 @@ import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.Resettable;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
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.ClusterConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.Clusterable;
|
||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||
|
@ -7,11 +7,11 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
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.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
@ -11,11 +11,11 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
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.rocketcomponent.MassComponent;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
@ -17,13 +17,13 @@ import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.MotorConfigurationModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.gui.main.MotorChooserDialog;
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
import net.sf.openrocket.rocketcomponent.Motor;
|
||||
|
@ -12,12 +12,12 @@ import javax.swing.JSlider;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.DescriptionArea;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.DescriptionArea;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
@ -11,13 +11,13 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.IntegerModel;
|
||||
import net.sf.openrocket.gui.adaptors.MaterialModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Parachute;
|
||||
|
@ -12,11 +12,11 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
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.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.RingComponent;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
@ -25,14 +25,14 @@ import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.MaterialModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
|
||||
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
||||
|
@ -7,11 +7,11 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
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.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
@ -12,13 +12,13 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.MaterialModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
@ -11,12 +11,12 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.DescriptionArea;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.DescriptionArea;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
|
@ -9,12 +9,12 @@ import javax.swing.JSpinner;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.IntegerModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
90
src/net/sf/openrocket/gui/dialogs/BugDialog.java
Normal file
90
src/net/sf/openrocket/gui/dialogs/BugDialog.java
Normal file
@ -0,0 +1,90 @@
|
||||
package net.sf.openrocket.gui.dialogs;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.components.URLLabel;
|
||||
import net.sf.openrocket.gui.main.AboutDialog;
|
||||
import net.sf.openrocket.util.GUIUtil;
|
||||
import net.sf.openrocket.util.JarUtil;
|
||||
import net.sf.openrocket.util.Prefs;
|
||||
|
||||
public class BugDialog extends JDialog {
|
||||
|
||||
public BugDialog(JFrame parent) {
|
||||
super(parent, "Bug reporing", true);
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
panel.add(new JLabel("Please report any bugs you encounter as instructed at "),
|
||||
"gap para, split 2");
|
||||
panel.add(new URLLabel(AboutDialog.OPENROCKET_URL), "wrap rel");
|
||||
panel.add(new JLabel("This allows us to make OpenRocket an even better simulator."),
|
||||
"gap para, wrap para");
|
||||
|
||||
panel.add(new JLabel("<html><em>Please copy and paste the following information " +
|
||||
"to the end of your bug report:</em>"), "gap para, wrap");
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('\n');
|
||||
sb.append("---------- Included system information ----------\n");
|
||||
sb.append("OpenRocket version: " + Prefs.getVersion() + "\n");
|
||||
sb.append("OpenRocket location: " + JarUtil.getCurrentJarFile() + "\n");
|
||||
sb.append("System properties:\n");
|
||||
|
||||
// Sort the keys
|
||||
SortedSet<String> keys = new TreeSet<String>();
|
||||
for (Object key: System.getProperties().keySet()) {
|
||||
keys.add((String)key);
|
||||
}
|
||||
|
||||
for (String key: keys) {
|
||||
String value = System.getProperty(key);
|
||||
sb.append(" " + key + "=");
|
||||
if (key.equals("line.separator")) {
|
||||
for (char c: value.toCharArray()) {
|
||||
sb.append(String.format("\\u%04x", (int)c));
|
||||
}
|
||||
} else {
|
||||
sb.append(value);
|
||||
}
|
||||
sb.append('\n');
|
||||
}
|
||||
|
||||
sb.append("---------- End system information ----------\n");
|
||||
sb.append('\n');
|
||||
|
||||
JTextArea text = new JTextArea(sb.toString(), 15, 70);
|
||||
text.setEditable(false);
|
||||
panel.add(new JScrollPane(text), "grow, wrap para");
|
||||
|
||||
JButton close = new JButton("Close");
|
||||
close.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
BugDialog.this.dispose();
|
||||
}
|
||||
});
|
||||
panel.add(close, "right");
|
||||
|
||||
this.add(panel);
|
||||
|
||||
this.pack();
|
||||
this.setLocationRelativeTo(parent);
|
||||
GUIUtil.installEscapeCloseOperation(this);
|
||||
GUIUtil.setDefaultButton(close);
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +1,16 @@
|
||||
package net.sf.openrocket.gui.main;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.URLLabel;
|
||||
import net.sf.openrocket.util.GUIUtil;
|
||||
import net.sf.openrocket.util.Prefs;
|
||||
|
||||
@ -37,33 +31,7 @@ public class AboutDialog extends JDialog {
|
||||
|
||||
panel.add(new ResizeLabel("Copyright \u00A9 2007-2009 Sampo Niskanen"), "ax 50%, wrap para");
|
||||
|
||||
JLabel link;
|
||||
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
|
||||
link = new JLabel("<html><a href=\"" + OPENROCKET_URL + "\">" +
|
||||
OPENROCKET_URL + "</a>");
|
||||
link.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
Desktop d = Desktop.getDesktop();
|
||||
try {
|
||||
d.browse(new URI(OPENROCKET_URL));
|
||||
|
||||
} catch (URISyntaxException e1) {
|
||||
throw new RuntimeException("BUG: Illegal OpenRocket URL: "+OPENROCKET_URL,
|
||||
e1);
|
||||
} catch (IOException e1) {
|
||||
System.err.println("Unable to launch browser:");
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
link = new JLabel(OPENROCKET_URL);
|
||||
}
|
||||
panel.add(link, "ax 50%, wrap para");
|
||||
panel.add(new URLLabel(OPENROCKET_URL), "ax 50%, wrap para");
|
||||
|
||||
|
||||
JButton close = new JButton("Close");
|
||||
|
@ -59,6 +59,7 @@ import net.sf.openrocket.gui.ComponentAnalysisDialog;
|
||||
import net.sf.openrocket.gui.PreferencesDialog;
|
||||
import net.sf.openrocket.gui.StorageOptionChooser;
|
||||
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
|
||||
import net.sf.openrocket.gui.dialogs.BugDialog;
|
||||
import net.sf.openrocket.gui.scalefigure.RocketPanel;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
|
||||
@ -87,6 +88,8 @@ public class BasicFrame extends JFrame {
|
||||
}
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
if (f.isDirectory())
|
||||
return true;
|
||||
String name = f.getName().toLowerCase();
|
||||
return name.endsWith(".ork") || name.endsWith(".ork.gz");
|
||||
}
|
||||
@ -117,7 +120,8 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
private RocketPanel rocketpanel;
|
||||
private ComponentTree tree = null;
|
||||
private final TreeSelectionModel selectionModel;
|
||||
private final TreeSelectionModel componentSelectionModel;
|
||||
// private final ListSelectionModel simulationSelectionModel; ...
|
||||
|
||||
/** Actions available for rocket modifications */
|
||||
private final RocketActions actions;
|
||||
@ -147,10 +151,10 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
|
||||
// Create the selection model that will be used
|
||||
selectionModel = new DefaultTreeSelectionModel();
|
||||
selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
componentSelectionModel = new DefaultTreeSelectionModel();
|
||||
componentSelectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
|
||||
actions = new RocketActions(document, selectionModel, this);
|
||||
actions = new RocketActions(document, componentSelectionModel, this);
|
||||
|
||||
|
||||
// The main vertical split pane
|
||||
@ -232,7 +236,7 @@ public class BasicFrame extends JFrame {
|
||||
JPanel panel = new JPanel(new MigLayout("fill, flowy","","[grow]"));
|
||||
|
||||
tree = new ComponentTree(rocket);
|
||||
tree.setSelectionModel(selectionModel);
|
||||
tree.setSelectionModel(componentSelectionModel);
|
||||
|
||||
// Remove JTree key events that interfere with menu accelerators
|
||||
InputMap im = SwingUtilities.getUIInputMap(tree, JComponent.WHEN_FOCUSED);
|
||||
@ -265,10 +269,10 @@ public class BasicFrame extends JFrame {
|
||||
tree.addMouseListener(ml);
|
||||
|
||||
// Update dialog when selection is changed
|
||||
selectionModel.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
componentSelectionModel.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
// Scroll tree to the selected item
|
||||
TreePath path = selectionModel.getSelectionPath();
|
||||
TreePath path = componentSelectionModel.getSelectionPath();
|
||||
if (path == null)
|
||||
return;
|
||||
tree.scrollPathToVisible(path);
|
||||
@ -313,7 +317,7 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
scroll = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
scroll.setViewportView(new ComponentAddButtons(document, selectionModel,
|
||||
scroll.setViewportView(new ComponentAddButtons(document, componentSelectionModel,
|
||||
scroll.getViewport()));
|
||||
scroll.setBorder(null);
|
||||
scroll.setViewportBorder(null);
|
||||
@ -513,6 +517,8 @@ public class BasicFrame extends JFrame {
|
||||
menu.getAccessibleContext().setAccessibleDescription("Information about OpenRocket");
|
||||
menubar.add(menu);
|
||||
|
||||
|
||||
|
||||
item = new JMenuItem("License",KeyEvent.VK_L);
|
||||
item.getAccessibleContext().setAccessibleDescription("OpenRocket license information");
|
||||
item.addActionListener(new ActionListener() {
|
||||
@ -522,6 +528,16 @@ public class BasicFrame extends JFrame {
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
item = new JMenuItem("Bug report",KeyEvent.VK_B);
|
||||
item.getAccessibleContext().setAccessibleDescription("Information about reporting " +
|
||||
"bugs in OpenRocket");
|
||||
item.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new BugDialog(BasicFrame.this).setVisible(true);
|
||||
}
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
item = new JMenuItem("About",KeyEvent.VK_A);
|
||||
item.getAccessibleContext().setAccessibleDescription("About OpenRocket");
|
||||
item.addActionListener(new ActionListener() {
|
||||
@ -537,14 +553,13 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
|
||||
|
||||
// TODO: HIGH: Remember last directory on open/save
|
||||
|
||||
private void openAction() {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setFileFilter(ROCKET_DESIGN_FILTER);
|
||||
chooser.setMultiSelectionEnabled(true);
|
||||
chooser.setCurrentDirectory(Prefs.getDefaultDirectory());
|
||||
if (chooser.showOpenDialog(BasicFrame.this) != JFileChooser.APPROVE_OPTION)
|
||||
if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION)
|
||||
return;
|
||||
|
||||
Prefs.setDefaultDirectory(chooser.getCurrentDirectory());
|
||||
|
@ -26,7 +26,7 @@ import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
|
||||
import net.sf.openrocket.rocketcomponent.BodyComponent;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
@ -40,12 +40,14 @@ import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||
import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||
import net.sf.openrocket.rocketcomponent.Parachute;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.ShockCord;
|
||||
import net.sf.openrocket.rocketcomponent.Streamer;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.TubeCoupler;
|
||||
import net.sf.openrocket.util.Pair;
|
||||
import net.sf.openrocket.util.Prefs;
|
||||
|
||||
/**
|
||||
@ -94,20 +96,6 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
// addButtonRow("Body components",row,
|
||||
// new ComponentButton(NoseCone.class,"Nose cone") {
|
||||
// @Override
|
||||
// public boolean isAddable(RocketComponent c) {
|
||||
// if (!(c instanceof ComponentAssembly))
|
||||
// return false;
|
||||
// if (c.getSiblingCount() == 0)
|
||||
// return true;
|
||||
// return false;
|
||||
// }
|
||||
// },
|
||||
// new BodyComponentButton(BodyTube.class,"Body tube"),
|
||||
// new BodyComponentButton(null,"Transition"));
|
||||
|
||||
|
||||
addButtonRow("Body components and fin sets",row,
|
||||
new BodyComponentButton(NoseCone.class,"Nose cone"),
|
||||
@ -120,7 +108,6 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
|
||||
);
|
||||
|
||||
row++;
|
||||
/////
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
@ -328,16 +315,16 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
|
||||
/**
|
||||
* Return the position to add the component if component c is selected currently.
|
||||
* The first element of the returned array is the RocketComponent to add the component
|
||||
* to, and the second (in any) an Integer telling the position of the component.
|
||||
* to, and the second (if non-null) an Integer telling the position of the component.
|
||||
* A return value of null means that the user cancelled addition of the component.
|
||||
* If the array has only one element, the component is added at the end of the sibling
|
||||
* If the Integer is null, the component is added at the end of the sibling
|
||||
* list. By default returns the end of the currently selected component.
|
||||
*
|
||||
* @param c The component currently selected
|
||||
* @return The position to add the new component to, or null if should not add.
|
||||
*/
|
||||
public Object[] getAdditionPosition(RocketComponent c) {
|
||||
return new Object[] { c };
|
||||
public Pair<RocketComponent, Integer> getAdditionPosition(RocketComponent c) {
|
||||
return new Pair<RocketComponent, Integer>(c, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -381,17 +368,15 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
|
||||
TreePath p = selectionModel.getSelectionPath();
|
||||
if (p!= null)
|
||||
c = (RocketComponent)p.getLastPathComponent();
|
||||
if (c != null) {
|
||||
Object[] pos = getAdditionPosition(c);
|
||||
if (pos==null || pos.length==0) {
|
||||
// Cancel addition
|
||||
return;
|
||||
}
|
||||
|
||||
c = (RocketComponent)pos[0];
|
||||
if (pos.length>1)
|
||||
position = (Integer)pos[1];
|
||||
Pair<RocketComponent, Integer> pos = getAdditionPosition(c);
|
||||
if (pos==null) {
|
||||
// Cancel addition
|
||||
return;
|
||||
}
|
||||
c = pos.getU();
|
||||
position = pos.getV();
|
||||
|
||||
|
||||
if (c == null) {
|
||||
// Should not occur
|
||||
@ -460,17 +445,27 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
|
||||
public boolean isAddable(RocketComponent c) {
|
||||
if (super.isAddable(c))
|
||||
return true;
|
||||
if (c instanceof BodyComponent) // Handled separately
|
||||
// Handled separately:
|
||||
if (c instanceof BodyComponent)
|
||||
return true;
|
||||
if (c == null || c instanceof Rocket)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getAdditionPosition(RocketComponent c) {
|
||||
public Pair<RocketComponent, Integer> getAdditionPosition(RocketComponent c) {
|
||||
if (super.isAddable(c)) // Handled automatically
|
||||
return super.getAdditionPosition(c);
|
||||
|
||||
// Handle BodyComponent separately
|
||||
|
||||
if (c == null || c instanceof Rocket) {
|
||||
// Add as last body component of the last stage
|
||||
Rocket rocket = document.getRocket();
|
||||
return new Pair<RocketComponent,Integer>(rocket.getChild(rocket.getStageCount()-1),
|
||||
null);
|
||||
}
|
||||
|
||||
if (!(c instanceof BodyComponent))
|
||||
return null;
|
||||
RocketComponent parent = c.getParent();
|
||||
@ -492,10 +487,10 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
|
||||
return null;
|
||||
case 1:
|
||||
// Insert after current position
|
||||
return new Object[] { parent, new Integer(parent.getChildPosition(c)+1) };
|
||||
return new Pair<RocketComponent,Integer>(parent, parent.getChildPosition(c)+1);
|
||||
case 2:
|
||||
// Insert at the end of the parent
|
||||
return new Object[] { parent };
|
||||
return new Pair<RocketComponent,Integer>(parent, null);
|
||||
default:
|
||||
System.err.println("ERROR: Bad position type: "+pos);
|
||||
Thread.dumpStack();
|
||||
|
@ -0,0 +1,15 @@
|
||||
package net.sf.openrocket.gui.main;
|
||||
|
||||
public interface DocumentSelectionListener {
|
||||
|
||||
public static final int COMPONENT_SELECTION_CHANGE = 1;
|
||||
public static final int SIMULATION_SELECTION_CHANGE = 2;
|
||||
|
||||
/**
|
||||
* Called when the selection changes.
|
||||
*
|
||||
* @param changeType a bitmask of the type of change.
|
||||
*/
|
||||
public void valueChanged(int changeType);
|
||||
|
||||
}
|
189
src/net/sf/openrocket/gui/main/DocumentSelectionModel.java
Normal file
189
src/net/sf/openrocket/gui/main/DocumentSelectionModel.java
Normal file
@ -0,0 +1,189 @@
|
||||
package net.sf.openrocket.gui.main;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
||||
public class DocumentSelectionModel {
|
||||
|
||||
private static final Simulation[] NO_SIMULATION = new Simulation[0];
|
||||
|
||||
private final ComponentTreeSelectionListener componentTreeSelectionListener =
|
||||
new ComponentTreeSelectionListener();
|
||||
private final SimulationListSelectionListener simulationListSelectionListener =
|
||||
new SimulationListSelectionListener();
|
||||
|
||||
|
||||
private final OpenRocketDocument document;
|
||||
|
||||
private RocketComponent componentSelection = null;
|
||||
private Simulation[] simulationSelection = NO_SIMULATION;
|
||||
|
||||
private TreeSelectionModel componentTreeSelectionModel = null;
|
||||
private ListSelectionModel simulationListSelectionModel = null;
|
||||
|
||||
private final List<DocumentSelectionListener> listeners =
|
||||
new ArrayList<DocumentSelectionListener>();
|
||||
|
||||
|
||||
|
||||
public DocumentSelectionModel(OpenRocketDocument document) {
|
||||
this.document = document;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the currently selected simulations. Returns an empty array if none
|
||||
* are selected.
|
||||
*
|
||||
* @return an array of the currently selected simulations, may be of zero length.
|
||||
*/
|
||||
public Simulation[] getSelectedSimulations() {
|
||||
return Arrays.copyOf(simulationSelection, simulationSelection.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the currently selected rocket component. Returns <code>null</code>
|
||||
* if no rocket component is selected.
|
||||
*
|
||||
* @return the currently selected rocket component, or <code>null</code>.
|
||||
*/
|
||||
public RocketComponent getSelectedComponent() {
|
||||
return componentSelection;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void attachComponentTreeSelectionModel(TreeSelectionModel model) {
|
||||
if (componentTreeSelectionModel != null)
|
||||
componentTreeSelectionModel.removeTreeSelectionListener(
|
||||
componentTreeSelectionListener);
|
||||
|
||||
componentTreeSelectionModel = model;
|
||||
if (model != null)
|
||||
model.addTreeSelectionListener(componentTreeSelectionListener);
|
||||
clearComponentSelection();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void attachSimulationListSelectionModel(ListSelectionModel model) {
|
||||
if (simulationListSelectionModel != null)
|
||||
simulationListSelectionModel.removeListSelectionListener(
|
||||
simulationListSelectionListener);
|
||||
|
||||
simulationListSelectionModel = model;
|
||||
if (model != null)
|
||||
model.addListSelectionListener(simulationListSelectionListener);
|
||||
clearSimulationSelection();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void clearSimulationSelection() {
|
||||
if (simulationSelection.length == 0)
|
||||
return;
|
||||
|
||||
simulationSelection = NO_SIMULATION;
|
||||
if (simulationListSelectionModel != null)
|
||||
simulationListSelectionModel.clearSelection();
|
||||
|
||||
fireDocumentSelection(DocumentSelectionListener.SIMULATION_SELECTION_CHANGE);
|
||||
}
|
||||
|
||||
|
||||
public void clearComponentSelection() {
|
||||
if (componentSelection == null)
|
||||
return;
|
||||
|
||||
componentSelection = null;
|
||||
if (componentTreeSelectionModel != null)
|
||||
componentTreeSelectionModel.clearSelection();
|
||||
|
||||
fireDocumentSelection(DocumentSelectionListener.COMPONENT_SELECTION_CHANGE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void addDocumentSelectionListener(DocumentSelectionListener l) {
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void removeDocumentSelectionListener(DocumentSelectionListener l) {
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
protected void fireDocumentSelection(int type) {
|
||||
DocumentSelectionListener[] array =
|
||||
listeners.toArray(new DocumentSelectionListener[0]);
|
||||
|
||||
for (DocumentSelectionListener l: array) {
|
||||
l.valueChanged(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class ComponentTreeSelectionListener implements TreeSelectionListener {
|
||||
|
||||
@Override
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
TreePath path = componentTreeSelectionModel.getSelectionPath();
|
||||
if (path == null) {
|
||||
componentSelection = null;
|
||||
fireDocumentSelection(DocumentSelectionListener.COMPONENT_SELECTION_CHANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
componentSelection = (RocketComponent)path.getLastPathComponent();
|
||||
|
||||
clearSimulationSelection();
|
||||
fireDocumentSelection(DocumentSelectionListener.COMPONENT_SELECTION_CHANGE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SimulationListSelectionListener implements ListSelectionListener {
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
int min = simulationListSelectionModel.getMinSelectionIndex();
|
||||
int max = simulationListSelectionModel.getMaxSelectionIndex();
|
||||
if (min < 0 || max < 0) {
|
||||
simulationSelection = NO_SIMULATION;
|
||||
fireDocumentSelection(DocumentSelectionListener.SIMULATION_SELECTION_CHANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<Simulation> list = new ArrayList<Simulation>();
|
||||
for (int i = min; i <= max; i++) {
|
||||
if (simulationListSelectionModel.isSelectedIndex(i) &&
|
||||
(i < document.getSimulationCount())) {
|
||||
list.add(document.getSimulation(i));
|
||||
}
|
||||
}
|
||||
simulationSelection = list.toArray(NO_SIMULATION);
|
||||
|
||||
clearComponentSelection();
|
||||
fireDocumentSelection(DocumentSelectionListener.SIMULATION_SELECTION_CHANGE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -14,7 +14,7 @@ import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.util.GUIUtil;
|
||||
|
||||
public class LicenseDialog extends JDialog {
|
||||
|
@ -32,7 +32,7 @@ import javax.swing.table.TableRowSorter;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.database.Databases;
|
||||
import net.sf.openrocket.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.rocketcomponent.Motor;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.GUIUtil;
|
||||
|
35
src/net/sf/openrocket/gui/main/OpenRocketClipboard.java
Normal file
35
src/net/sf/openrocket/gui/main/OpenRocketClipboard.java
Normal file
@ -0,0 +1,35 @@
|
||||
package net.sf.openrocket.gui.main;
|
||||
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
||||
public class OpenRocketClipboard {
|
||||
|
||||
private static Object clipboard = null;
|
||||
|
||||
private OpenRocketClipboard() {
|
||||
// Disallow instantiation
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the <code>RocketComponent</code> contained in the clipboard, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Simulation[] getSimulations() {
|
||||
return null; // TODO
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -28,7 +28,7 @@ import net.sf.openrocket.util.Pair;
|
||||
|
||||
|
||||
/**
|
||||
* A class that holds Actions for common rocket operations such as
|
||||
* A class that holds Actions for common rocket and simulation operations such as
|
||||
* cut/copy/paste/delete etc.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
|
@ -32,13 +32,13 @@ import javax.swing.event.DocumentListener;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.aerodynamics.ExtendedISAModel;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.DescriptionArea;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.MotorConfigurationModel;
|
||||
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.gui.plot.Axis;
|
||||
import net.sf.openrocket.gui.plot.PlotConfiguration;
|
||||
import net.sf.openrocket.gui.plot.PlotPanel;
|
||||
|
@ -25,9 +25,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.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.adaptors.Column;
|
||||
import net.sf.openrocket.gui.adaptors.ColumnTableModel;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
|
||||
import net.sf.openrocket.simulation.FlightData;
|
||||
|
@ -16,8 +16,8 @@ import javax.swing.SwingUtilities;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.gui.ResizeLabel;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.components.ResizeLabel;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.simulation.FlightDataBranch;
|
||||
import net.sf.openrocket.simulation.FlightDataBranch.Type;
|
||||
import net.sf.openrocket.unit.Unit;
|
||||
|
@ -37,11 +37,11 @@ import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.gui.BasicSlider;
|
||||
import net.sf.openrocket.gui.StageSelector;
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.MotorConfigurationModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.StageSelector;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
|
||||
import net.sf.openrocket.gui.figureelements.CGCaret;
|
||||
import net.sf.openrocket.gui.figureelements.CPCaret;
|
||||
@ -360,7 +360,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
*
|
||||
* Get the components clicked.
|
||||
* If no component is clicked, do nothing.
|
||||
* If the primary currently selected component is in the set, keep it,
|
||||
* If the currently selected component is in the set, keep it,
|
||||
* unless the selector specified is pressed. If it is pressed, cycle to
|
||||
* the next component. Otherwise select the first component in the list.
|
||||
*/
|
||||
@ -399,7 +399,11 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
// Currently selected component not clicked
|
||||
if (path == null) {
|
||||
path = ComponentTreeModel.makeTreePath(clicked[0]);
|
||||
if (event.isShiftDown() && event.getClickCount()==1 && clicked.length>1) {
|
||||
path = ComponentTreeModel.makeTreePath(clicked[1]);
|
||||
} else {
|
||||
path = ComponentTreeModel.makeTreePath(clicked[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Set selection and check for double-click
|
||||
|
@ -23,8 +23,8 @@ import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.sf.openrocket.gui.UnitSelector;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.unit.Tick;
|
||||
import net.sf.openrocket.unit.Unit;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
180
src/net/sf/openrocket/startup/Startup.java
Normal file
180
src/net/sf/openrocket/startup/Startup.java
Normal file
@ -0,0 +1,180 @@
|
||||
package net.sf.openrocket.startup;
|
||||
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
|
||||
/**
|
||||
* A startup class that checks that a suitable JRE environment is being run.
|
||||
* If the environment is too old the execution is canceled, and if OpenJDK is being
|
||||
* used warns the user of problems and confirms whether to continue.
|
||||
* <p>
|
||||
* Note: This class must be Java 1.4 compatible and calls the next class using
|
||||
* only reflection.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class Startup {
|
||||
|
||||
public static final String START_CLASS = "net.sf.openrocket.gui.main.BasicFrame";
|
||||
|
||||
public static final int REQUIRED_MAJOR_VERSION = 1;
|
||||
public static final int REQUIRED_MINOR_VERSION = 6;
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
checkVersion();
|
||||
checkHead();
|
||||
checkOpenJDK();
|
||||
|
||||
// Load and execute START_CLASS
|
||||
try {
|
||||
|
||||
Class cls = Class.forName(START_CLASS);
|
||||
Method m = cls.getMethod("main", String[].class);
|
||||
m.invoke(null, new Object[] { args });
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
error("Error starting main class!", "Please report a bug.");
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
error("Error starting main class!", "Please report a bug.");
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
error("Error starting main class!", "Please report a bug.");
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
error("Error starting main class!", "Please report a bug.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check that the JRE version is high enough.
|
||||
*/
|
||||
private static void checkVersion() {
|
||||
String[] version = System.getProperty("java.specification.version", "").split("\\.");
|
||||
|
||||
String jreName = System.getProperty("java.vm.name", "(unknown)");
|
||||
String jreVersion = System.getProperty("java.runtime.version", "(unknown)");
|
||||
String jreVendor = System.getProperty("java.vendor", "(unknown)");
|
||||
|
||||
int major, minor;
|
||||
|
||||
try {
|
||||
major = Integer.parseInt(version[0]);
|
||||
minor = Integer.parseInt(version[1]);
|
||||
|
||||
if (major < REQUIRED_MAJOR_VERSION ||
|
||||
(major == REQUIRED_MAJOR_VERSION && minor < REQUIRED_MINOR_VERSION)) {
|
||||
error("Java SE version 6 is required to run OpenRocket.",
|
||||
"You are currently running " + jreName + " version " +
|
||||
jreVersion + " by " + jreVendor);
|
||||
}
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
|
||||
confirm("The Java version in use could not be detected.",
|
||||
"OpenRocket requires at least Java SE 6.",
|
||||
"Continue anyway?");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check that the JRE is not running headless.
|
||||
*/
|
||||
private static void checkHead() {
|
||||
|
||||
if (GraphicsEnvironment.isHeadless()) {
|
||||
System.err.println();
|
||||
System.err.println("OpenRocket cannot currently be run without the graphical " +
|
||||
"user interface.");
|
||||
System.err.println();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether OpenJDK is being used, and if it is warn the user about
|
||||
* problems and confirm whether to continue.
|
||||
*/
|
||||
private static void checkOpenJDK() {
|
||||
|
||||
if (System.getProperty("java.runtime.name", "").toLowerCase().indexOf("icedtea")>=0 ||
|
||||
System.getProperty("java.vm.name", "").toLowerCase().indexOf("openjdk")>=0) {
|
||||
|
||||
String jreName = System.getProperty("java.vm.name", "(unknown)");
|
||||
String jreVersion = System.getProperty("java.runtime.version", "(unknown)");
|
||||
String jreVendor = System.getProperty("java.vendor", "(unknown)");
|
||||
|
||||
confirm("OpenJDK is known to have problems running OpenRocket.",
|
||||
" ",
|
||||
"You are currently running " + jreName + " version " +
|
||||
jreVersion + " by " + jreVendor,
|
||||
"Do you want to continue?");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Presents an error message to the user and exits the application.
|
||||
*
|
||||
* @param message an array of messages to present.
|
||||
*/
|
||||
private static void error(String ... message) {
|
||||
|
||||
System.err.println();
|
||||
System.err.println("Error starting OpenRocket:");
|
||||
System.err.println();
|
||||
for (int i=0; i < message.length; i++) {
|
||||
System.err.println(message[i]);
|
||||
}
|
||||
System.err.println();
|
||||
|
||||
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
|
||||
JOptionPane.showMessageDialog(null, message, "Error starting OpenRocket",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
|
||||
}
|
||||
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Presents the user with a message dialog and asks whether to continue.
|
||||
* If the user does not select "Yes" the the application exits.
|
||||
*
|
||||
* @param message the message Strings to show.
|
||||
*/
|
||||
private static void confirm(String ... message) {
|
||||
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
|
||||
if (JOptionPane.showConfirmDialog(null, message, "Error starting OpenRocket",
|
||||
JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -47,7 +47,7 @@ public class FixedPrecisionUnit extends Unit {
|
||||
|
||||
@Override
|
||||
public String toString(double value) {
|
||||
return String.format(formatString, value);
|
||||
return String.format(formatString, this.toUnit(value));
|
||||
}
|
||||
|
||||
|
||||
|
50
src/net/sf/openrocket/util/JarUtil.java
Normal file
50
src/net/sf/openrocket/util/JarUtil.java
Normal file
@ -0,0 +1,50 @@
|
||||
package net.sf.openrocket.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.security.CodeSource;
|
||||
|
||||
import net.sf.openrocket.database.Database;
|
||||
|
||||
public class JarUtil {
|
||||
|
||||
/**
|
||||
* Return the a File object pointing to the JAR file that this class belongs to,
|
||||
* or <code>null</code> if it cannot be found.
|
||||
*
|
||||
* @return a File object of the current Java archive, or <code>null</code>
|
||||
*/
|
||||
public static File getCurrentJarFile() {
|
||||
// Find the jar file this class is contained in
|
||||
URL jarUrl = null;
|
||||
CodeSource codeSource = Database.class.getProtectionDomain().getCodeSource();
|
||||
if (codeSource != null)
|
||||
jarUrl = codeSource.getLocation();
|
||||
|
||||
if (jarUrl == null) {
|
||||
return null;
|
||||
}
|
||||
return urlToFile(jarUrl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static File urlToFile(URL url) {
|
||||
URI uri;
|
||||
try {
|
||||
uri = url.toURI();
|
||||
} catch (URISyntaxException e) {
|
||||
try {
|
||||
uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
|
||||
url.getPort(), url.getPath(), url.getQuery(), url.getRef());
|
||||
} catch (URISyntaxException e1) {
|
||||
throw new IllegalArgumentException("Broken URL: " + url);
|
||||
}
|
||||
}
|
||||
return new File(uri);
|
||||
}
|
||||
|
||||
|
||||
}
|
22
src/net/sf/openrocket/util/PrintProperties.java
Normal file
22
src/net/sf/openrocket/util/PrintProperties.java
Normal file
@ -0,0 +1,22 @@
|
||||
package net.sf.openrocket.util;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class PrintProperties {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Sort the keys
|
||||
SortedSet<String> keys = new TreeSet<String>();
|
||||
for (Object key: System.getProperties().keySet()) {
|
||||
keys.add((String)key);
|
||||
}
|
||||
|
||||
for (String key: keys) {
|
||||
System.out.println(key + "=" + System.getProperty((String)key));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user