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>
* Initial release 0.9.0

View File

@ -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 -->

View File

@ -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>

View File

@ -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) {

View File

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

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.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;

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
package net.sf.openrocket.gui;
package net.sf.openrocket.gui.components;
import javax.swing.BoundedRangeModel;
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.Rectangle;

View File

@ -1,4 +1,4 @@
package net.sf.openrocket.gui;
package net.sf.openrocket.gui.components;
import java.awt.Font;
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.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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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;
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");

View File

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

View File

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

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 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 {

View File

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

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.
*
* @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.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;

View File

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

View File

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

View File

@ -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

View File

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

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