Bug fixes and startup checks

This commit is contained in:
Sampo Niskanen 2009-05-31 17:50:09 +00:00
parent e246eb1f17
commit 2f7baaa87c
49 changed files with 774 additions and 171 deletions

View File

@ -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> 2009-05-24 Sampo Niskanen <sampo.niskanen@iki.fi>
* Initial release 0.9.0 * Initial release 0.9.0

View File

@ -12,7 +12,7 @@
<!-- The main class of the application --> <!-- 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 --> <!-- Classpath definition -->

View File

@ -76,7 +76,7 @@
<p>The source code for OpenRocket is available from the <p>The source code for OpenRocket is available from the
<a href="http://openrocket.svn.sourceforge.net/viewvc/openrocket/">SourceForge SVN repository</a>. <a href="http://openrocket.svn.sourceforge.net/viewvc/openrocket/">SourceForge SVN repository</a>.
It can be retrieved simply using the command</p> 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 <p>The above URL may be used to connect to the repository with
other Subversion clients as well.</p> other Subversion clients as well.</p>

View File

@ -5,10 +5,6 @@ import java.io.FileInputStream;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; 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.AbstractSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -24,6 +20,7 @@ import javax.swing.event.EventListenerList;
import net.sf.openrocket.file.Loader; import net.sf.openrocket.file.Loader;
import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.ChangeSource;
import net.sf.openrocket.util.JarUtil;
@ -183,16 +180,8 @@ public class Database<T extends Comparable<T>> extends AbstractSet<T> implements
dir += "/"; dir += "/";
} }
// Find the jar file this class is contained in and open it // Find and open the jar file this class is contained in
URL jarUrl = null; File file = JarUtil.getCurrentJarFile();
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);
JarFile jarFile = new JarFile(file); JarFile jarFile = new JarFile(file);
try { 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 { public void load(File file) throws IOException {
if (loader == null) { if (loader == null) {

View File

@ -33,7 +33,7 @@ public class TransitionSaver extends SymmetricComponentSaver {
Transition.Shape shape = trans.getType(); Transition.Shape shape = trans.getType();
elements.add("<shape>" + shape.getName().toLowerCase() + "</shape>"); elements.add("<shape>" + shape.name().toLowerCase() + "</shape>");
if (shape.isClippable()) { if (shape.isClippable()) {
elements.add("<shapeclipped>" + trans.isClipped() + "</shapeclipped>"); elements.add("<shapeclipped>" + trans.isClipped() + "</shapeclipped>");
} }

View File

@ -44,6 +44,10 @@ import net.sf.openrocket.gui.adaptors.Column;
import net.sf.openrocket.gui.adaptors.ColumnTableModel; import net.sf.openrocket.gui.adaptors.ColumnTableModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.MotorConfigurationModel; 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.gui.scalefigure.RocketPanel;
import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.Configuration;
import net.sf.openrocket.rocketcomponent.FinSet; import net.sf.openrocket.rocketcomponent.FinSet;

View File

@ -18,6 +18,7 @@ import javax.swing.JPanel;
import javax.swing.JTabbedPane; import javax.swing.JTabbedPane;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.components.ResizeLabel;
import net.sf.openrocket.unit.Unit; import net.sf.openrocket.unit.Unit;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.GUIUtil; import net.sf.openrocket.util.GUIUtil;

View File

@ -20,7 +20,7 @@ import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.database.Database; import net.sf.openrocket.database.Database;
import net.sf.openrocket.database.Databases; 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.material.Material;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;

View File

@ -30,8 +30,8 @@ import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.ResizeLabel;
import net.sf.openrocket.gui.TextFieldListener; import net.sf.openrocket.gui.TextFieldListener;
import net.sf.openrocket.gui.components.ResizeLabel;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.Configuration;
import net.sf.openrocket.rocketcomponent.Motor; import net.sf.openrocket.rocketcomponent.Motor;

View File

@ -1,4 +1,4 @@
package net.sf.openrocket.gui; package net.sf.openrocket.gui.components;
import javax.swing.BoundedRangeModel; import javax.swing.BoundedRangeModel;
import javax.swing.JSlider; import javax.swing.JSlider;

View File

@ -1,4 +1,4 @@
package net.sf.openrocket.gui; package net.sf.openrocket.gui.components;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Rectangle; import java.awt.Rectangle;

View File

@ -1,4 +1,4 @@
package net.sf.openrocket.gui; package net.sf.openrocket.gui.components;
import java.awt.Font; import java.awt.Font;
import javax.swing.JLabel; import javax.swing.JLabel;

View File

@ -1,4 +1,4 @@
package net.sf.openrocket.gui; package net.sf.openrocket.gui.components;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.ArrayList; import java.util.ArrayList;

View 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);
}
}
}

View File

@ -1,4 +1,4 @@
package net.sf.openrocket.gui; package net.sf.openrocket.gui.components;
import java.awt.Color; import java.awt.Color;

View File

@ -7,11 +7,11 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.SpinnerEditor; 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.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;

View File

@ -14,12 +14,12 @@ import javax.swing.SwingConstants;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.SpinnerEditor; 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.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.adaptors.IntegerModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.FinSet; import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.FreeformFinSet; import net.sf.openrocket.rocketcomponent.FreeformFinSet;

View File

@ -17,13 +17,13 @@ import javax.swing.SwingConstants;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import net.miginfocom.swing.MigLayout; 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.SpinnerEditor;
import net.sf.openrocket.gui.UnitSelector;
import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.adaptors.IntegerModel; 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.FinPointFigure;
import net.sf.openrocket.gui.scalefigure.ScaleScrollPane; import net.sf.openrocket.gui.scalefigure.ScaleScrollPane;
import net.sf.openrocket.gui.scalefigure.ScaleSelector; import net.sf.openrocket.gui.scalefigure.ScaleSelector;

View File

@ -26,11 +26,11 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.Resettable; import net.sf.openrocket.gui.Resettable;
import net.sf.openrocket.gui.SpinnerEditor; 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.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.ClusterConfiguration;
import net.sf.openrocket.rocketcomponent.Clusterable; import net.sf.openrocket.rocketcomponent.Clusterable;
import net.sf.openrocket.rocketcomponent.InnerTube; import net.sf.openrocket.rocketcomponent.InnerTube;

View File

@ -7,11 +7,11 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.SpinnerEditor; 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.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;

View File

@ -11,11 +11,11 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.SpinnerEditor; 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.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; 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.MassComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;

View File

@ -17,13 +17,13 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.SpinnerEditor; 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.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.adaptors.MotorConfigurationModel; 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.gui.main.MotorChooserDialog;
import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.Configuration;
import net.sf.openrocket.rocketcomponent.Motor; import net.sf.openrocket.rocketcomponent.Motor;

View File

@ -12,12 +12,12 @@ import javax.swing.JSlider;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; 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.SpinnerEditor;
import net.sf.openrocket.gui.UnitSelector;
import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.NoseCone; import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;

View File

@ -11,13 +11,13 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.SpinnerEditor; 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.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.adaptors.IntegerModel; import net.sf.openrocket.gui.adaptors.IntegerModel;
import net.sf.openrocket.gui.adaptors.MaterialModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.MassComponent; import net.sf.openrocket.rocketcomponent.MassComponent;
import net.sf.openrocket.rocketcomponent.Parachute; import net.sf.openrocket.rocketcomponent.Parachute;

View File

@ -12,11 +12,11 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.SpinnerEditor; 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.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.RingComponent; import net.sf.openrocket.rocketcomponent.RingComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;

View File

@ -25,14 +25,14 @@ import javax.swing.JTextArea;
import javax.swing.JTextField; import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout; 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.SpinnerEditor;
import net.sf.openrocket.gui.UnitSelector;
import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.adaptors.MaterialModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.ExternalComponent; import net.sf.openrocket.rocketcomponent.ExternalComponent;

View File

@ -7,11 +7,11 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.SpinnerEditor; 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.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;

View File

@ -12,13 +12,13 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; 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.SpinnerEditor;
import net.sf.openrocket.gui.UnitSelector;
import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.adaptors.MaterialModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.MassComponent; import net.sf.openrocket.rocketcomponent.MassComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;

View File

@ -11,12 +11,12 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; 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.SpinnerEditor;
import net.sf.openrocket.gui.UnitSelector;
import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.rocketcomponent.Transition;

View File

@ -9,12 +9,12 @@ import javax.swing.JSpinner;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.BasicSlider;
import net.sf.openrocket.gui.SpinnerEditor; 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.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.adaptors.IntegerModel; 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.material.Material;
import net.sf.openrocket.rocketcomponent.FinSet; import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;

View 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);
}
}

View File

@ -1,22 +1,16 @@
package net.sf.openrocket.gui.main; package net.sf.openrocket.gui.main;
import java.awt.Desktop;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; 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.JButton;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout; 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.GUIUtil;
import net.sf.openrocket.util.Prefs; 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"); panel.add(new ResizeLabel("Copyright \u00A9 2007-2009 Sampo Niskanen"), "ax 50%, wrap para");
JLabel link; panel.add(new URLLabel(OPENROCKET_URL), "ax 50%, wrap para");
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");
JButton close = new JButton("Close"); JButton close = new JButton("Close");

View File

@ -59,6 +59,7 @@ import net.sf.openrocket.gui.ComponentAnalysisDialog;
import net.sf.openrocket.gui.PreferencesDialog; import net.sf.openrocket.gui.PreferencesDialog;
import net.sf.openrocket.gui.StorageOptionChooser; import net.sf.openrocket.gui.StorageOptionChooser;
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog; 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.gui.scalefigure.RocketPanel;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.ComponentChangeListener; import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
@ -87,6 +88,8 @@ public class BasicFrame extends JFrame {
} }
@Override @Override
public boolean accept(File f) { public boolean accept(File f) {
if (f.isDirectory())
return true;
String name = f.getName().toLowerCase(); String name = f.getName().toLowerCase();
return name.endsWith(".ork") || name.endsWith(".ork.gz"); return name.endsWith(".ork") || name.endsWith(".ork.gz");
} }
@ -117,7 +120,8 @@ public class BasicFrame extends JFrame {
private RocketPanel rocketpanel; private RocketPanel rocketpanel;
private ComponentTree tree = null; private ComponentTree tree = null;
private final TreeSelectionModel selectionModel; private final TreeSelectionModel componentSelectionModel;
// private final ListSelectionModel simulationSelectionModel; ...
/** Actions available for rocket modifications */ /** Actions available for rocket modifications */
private final RocketActions actions; private final RocketActions actions;
@ -147,10 +151,10 @@ public class BasicFrame extends JFrame {
// Create the selection model that will be used // Create the selection model that will be used
selectionModel = new DefaultTreeSelectionModel(); componentSelectionModel = new DefaultTreeSelectionModel();
selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); componentSelectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
actions = new RocketActions(document, selectionModel, this); actions = new RocketActions(document, componentSelectionModel, this);
// The main vertical split pane // The main vertical split pane
@ -232,7 +236,7 @@ public class BasicFrame extends JFrame {
JPanel panel = new JPanel(new MigLayout("fill, flowy","","[grow]")); JPanel panel = new JPanel(new MigLayout("fill, flowy","","[grow]"));
tree = new ComponentTree(rocket); tree = new ComponentTree(rocket);
tree.setSelectionModel(selectionModel); tree.setSelectionModel(componentSelectionModel);
// Remove JTree key events that interfere with menu accelerators // Remove JTree key events that interfere with menu accelerators
InputMap im = SwingUtilities.getUIInputMap(tree, JComponent.WHEN_FOCUSED); InputMap im = SwingUtilities.getUIInputMap(tree, JComponent.WHEN_FOCUSED);
@ -265,10 +269,10 @@ public class BasicFrame extends JFrame {
tree.addMouseListener(ml); tree.addMouseListener(ml);
// Update dialog when selection is changed // Update dialog when selection is changed
selectionModel.addTreeSelectionListener(new TreeSelectionListener() { componentSelectionModel.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) { public void valueChanged(TreeSelectionEvent e) {
// Scroll tree to the selected item // Scroll tree to the selected item
TreePath path = selectionModel.getSelectionPath(); TreePath path = componentSelectionModel.getSelectionPath();
if (path == null) if (path == null)
return; return;
tree.scrollPathToVisible(path); tree.scrollPathToVisible(path);
@ -313,7 +317,7 @@ public class BasicFrame extends JFrame {
scroll = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, scroll = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setViewportView(new ComponentAddButtons(document, selectionModel, scroll.setViewportView(new ComponentAddButtons(document, componentSelectionModel,
scroll.getViewport())); scroll.getViewport()));
scroll.setBorder(null); scroll.setBorder(null);
scroll.setViewportBorder(null); scroll.setViewportBorder(null);
@ -513,6 +517,8 @@ public class BasicFrame extends JFrame {
menu.getAccessibleContext().setAccessibleDescription("Information about OpenRocket"); menu.getAccessibleContext().setAccessibleDescription("Information about OpenRocket");
menubar.add(menu); menubar.add(menu);
item = new JMenuItem("License",KeyEvent.VK_L); item = new JMenuItem("License",KeyEvent.VK_L);
item.getAccessibleContext().setAccessibleDescription("OpenRocket license information"); item.getAccessibleContext().setAccessibleDescription("OpenRocket license information");
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@ -522,6 +528,16 @@ public class BasicFrame extends JFrame {
}); });
menu.add(item); 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 = new JMenuItem("About",KeyEvent.VK_A);
item.getAccessibleContext().setAccessibleDescription("About OpenRocket"); item.getAccessibleContext().setAccessibleDescription("About OpenRocket");
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@ -537,14 +553,13 @@ public class BasicFrame extends JFrame {
// TODO: HIGH: Remember last directory on open/save
private void openAction() { private void openAction() {
JFileChooser chooser = new JFileChooser(); JFileChooser chooser = new JFileChooser();
chooser.setFileFilter(ROCKET_DESIGN_FILTER); chooser.setFileFilter(ROCKET_DESIGN_FILTER);
chooser.setMultiSelectionEnabled(true); chooser.setMultiSelectionEnabled(true);
chooser.setCurrentDirectory(Prefs.getDefaultDirectory()); chooser.setCurrentDirectory(Prefs.getDefaultDirectory());
if (chooser.showOpenDialog(BasicFrame.this) != JFileChooser.APPROVE_OPTION) if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION)
return; return;
Prefs.setDefaultDirectory(chooser.getCurrentDirectory()); Prefs.setDefaultDirectory(chooser.getCurrentDirectory());

View File

@ -26,7 +26,7 @@ import javax.swing.tree.TreeSelectionModel;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.document.OpenRocketDocument; 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.gui.configdialog.ComponentConfigDialog;
import net.sf.openrocket.rocketcomponent.BodyComponent; import net.sf.openrocket.rocketcomponent.BodyComponent;
import net.sf.openrocket.rocketcomponent.BodyTube; 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.MassComponent;
import net.sf.openrocket.rocketcomponent.NoseCone; import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.Parachute; import net.sf.openrocket.rocketcomponent.Parachute;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.ShockCord; import net.sf.openrocket.rocketcomponent.ShockCord;
import net.sf.openrocket.rocketcomponent.Streamer; import net.sf.openrocket.rocketcomponent.Streamer;
import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet; import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
import net.sf.openrocket.rocketcomponent.TubeCoupler; import net.sf.openrocket.rocketcomponent.TubeCoupler;
import net.sf.openrocket.util.Pair;
import net.sf.openrocket.util.Prefs; 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, addButtonRow("Body components and fin sets",row,
new BodyComponentButton(NoseCone.class,"Nose cone"), new BodyComponentButton(NoseCone.class,"Nose cone"),
@ -120,7 +108,6 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
); );
row++; 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. * 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 * 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. * 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. * list. By default returns the end of the currently selected component.
* *
* @param c The component currently selected * @param c The component currently selected
* @return The position to add the new component to, or null if should not add. * @return The position to add the new component to, or null if should not add.
*/ */
public Object[] getAdditionPosition(RocketComponent c) { public Pair<RocketComponent, Integer> getAdditionPosition(RocketComponent c) {
return new Object[] { c }; return new Pair<RocketComponent, Integer>(c, null);
} }
/** /**
@ -381,17 +368,15 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
TreePath p = selectionModel.getSelectionPath(); TreePath p = selectionModel.getSelectionPath();
if (p!= null) if (p!= null)
c = (RocketComponent)p.getLastPathComponent(); c = (RocketComponent)p.getLastPathComponent();
if (c != null) {
Object[] pos = getAdditionPosition(c); Pair<RocketComponent, Integer> pos = getAdditionPosition(c);
if (pos==null || pos.length==0) { if (pos==null) {
// Cancel addition // Cancel addition
return; return;
} }
c = pos.getU();
position = pos.getV();
c = (RocketComponent)pos[0];
if (pos.length>1)
position = (Integer)pos[1];
}
if (c == null) { if (c == null) {
// Should not occur // Should not occur
@ -460,17 +445,27 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
public boolean isAddable(RocketComponent c) { public boolean isAddable(RocketComponent c) {
if (super.isAddable(c)) if (super.isAddable(c))
return true; 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 true;
return false; return false;
} }
@Override @Override
public Object[] getAdditionPosition(RocketComponent c) { public Pair<RocketComponent, Integer> getAdditionPosition(RocketComponent c) {
if (super.isAddable(c)) // Handled automatically if (super.isAddable(c)) // Handled automatically
return super.getAdditionPosition(c); 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)) if (!(c instanceof BodyComponent))
return null; return null;
RocketComponent parent = c.getParent(); RocketComponent parent = c.getParent();
@ -492,10 +487,10 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
return null; return null;
case 1: case 1:
// Insert after current position // 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: case 2:
// Insert at the end of the parent // Insert at the end of the parent
return new Object[] { parent }; return new Pair<RocketComponent,Integer>(parent, null);
default: default:
System.err.println("ERROR: Bad position type: "+pos); System.err.println("ERROR: Bad position type: "+pos);
Thread.dumpStack(); Thread.dumpStack();

View File

@ -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);
}

View 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);
}
}
}

View File

@ -14,7 +14,7 @@ import javax.swing.JScrollPane;
import javax.swing.JTextArea; import javax.swing.JTextArea;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.ResizeLabel; import net.sf.openrocket.gui.components.ResizeLabel;
import net.sf.openrocket.util.GUIUtil; import net.sf.openrocket.util.GUIUtil;
public class LicenseDialog extends JDialog { public class LicenseDialog extends JDialog {

View File

@ -32,7 +32,7 @@ import javax.swing.table.TableRowSorter;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.database.Databases; 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.rocketcomponent.Motor;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.GUIUtil; import net.sf.openrocket.util.GUIUtil;

View 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
}
}

View File

@ -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. * cut/copy/paste/delete etc.
* *
* @author Sampo Niskanen <sampo.niskanen@iki.fi> * @author Sampo Niskanen <sampo.niskanen@iki.fi>

View File

@ -32,13 +32,13 @@ import javax.swing.event.DocumentListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.aerodynamics.ExtendedISAModel; import net.sf.openrocket.aerodynamics.ExtendedISAModel;
import net.sf.openrocket.document.Simulation; 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.SpinnerEditor;
import net.sf.openrocket.gui.UnitSelector;
import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.MotorConfigurationModel; 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.Axis;
import net.sf.openrocket.gui.plot.PlotConfiguration; import net.sf.openrocket.gui.plot.PlotConfiguration;
import net.sf.openrocket.gui.plot.PlotPanel; import net.sf.openrocket.gui.plot.PlotPanel;

View File

@ -25,9 +25,9 @@ import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation; 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.Column;
import net.sf.openrocket.gui.adaptors.ColumnTableModel; 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.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.ComponentChangeListener; import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
import net.sf.openrocket.simulation.FlightData; import net.sf.openrocket.simulation.FlightData;

View File

@ -16,8 +16,8 @@ import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.gui.ResizeLabel; import net.sf.openrocket.gui.components.ResizeLabel;
import net.sf.openrocket.gui.UnitSelector; import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.simulation.FlightDataBranch; import net.sf.openrocket.simulation.FlightDataBranch;
import net.sf.openrocket.simulation.FlightDataBranch.Type; import net.sf.openrocket.simulation.FlightDataBranch.Type;
import net.sf.openrocket.unit.Unit; import net.sf.openrocket.unit.Unit;

View File

@ -37,11 +37,11 @@ import net.sf.openrocket.aerodynamics.FlightConditions;
import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation; 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.DoubleModel;
import net.sf.openrocket.gui.adaptors.MotorConfigurationModel; 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.configdialog.ComponentConfigDialog;
import net.sf.openrocket.gui.figureelements.CGCaret; import net.sf.openrocket.gui.figureelements.CGCaret;
import net.sf.openrocket.gui.figureelements.CPCaret; import net.sf.openrocket.gui.figureelements.CPCaret;
@ -360,7 +360,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
* *
* Get the components clicked. * Get the components clicked.
* If no component is clicked, do nothing. * 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 * unless the selector specified is pressed. If it is pressed, cycle to
* the next component. Otherwise select the first component in the list. * the next component. Otherwise select the first component in the list.
*/ */
@ -399,8 +399,12 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
// Currently selected component not clicked // Currently selected component not clicked
if (path == null) { if (path == null) {
if (event.isShiftDown() && event.getClickCount()==1 && clicked.length>1) {
path = ComponentTreeModel.makeTreePath(clicked[1]);
} else {
path = ComponentTreeModel.makeTreePath(clicked[0]); path = ComponentTreeModel.makeTreePath(clicked[0]);
} }
}
// Set selection and check for double-click // Set selection and check for double-click
selectionModel.setSelectionPath(path); selectionModel.setSelectionPath(path);

View File

@ -23,8 +23,8 @@ import javax.swing.ScrollPaneConstants;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import net.sf.openrocket.gui.UnitSelector;
import net.sf.openrocket.gui.adaptors.DoubleModel; 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.Tick;
import net.sf.openrocket.unit.Unit; import net.sf.openrocket.unit.Unit;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;

View 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);
}
}
}
}

View File

@ -47,7 +47,7 @@ public class FixedPrecisionUnit extends Unit {
@Override @Override
public String toString(double value) { public String toString(double value) {
return String.format(formatString, value); return String.format(formatString, this.toUnit(value));
} }

View 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);
}
}

View 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));
}
}
}