diff --git a/.classpath b/.classpath index 290b5a5e7..fc1bd663e 100644 --- a/.classpath +++ b/.classpath @@ -2,10 +2,12 @@ + + diff --git a/ChangeLog b/ChangeLog index 75658dd24..44f2149e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-08-29 Sampo Niskanen + + * Extracted motor manufacturer into separate class + * Started writing unit tests + +2009-08-28 Sampo Niskanen + + * Added icon and source info to About dialog + * Finalized flight event plot icons + 2009-08-27 Sampo Niskanen * Allow clicking on label to toggle checkbox in two tables diff --git a/TODO b/TODO index 6bcc1be1f..0309f3e27 100644 --- a/TODO +++ b/TODO @@ -4,15 +4,11 @@ Feature roadmap for OpenRocket 1.0 Must-have: -- Draw remaining event icons (for 0.9.3) -- Change automatic exception reporting success code to 202 (for 0.9.3) -- Test automatic exception reporting (for 0.9.3) - Allow editing user-defined materials - Go through thrust curves and correct errors - Add styrofoam and depron materials - Through-the-wall fins -- Update "About" dialog with icon and source info Bugs: @@ -56,4 +52,7 @@ Done: - Read more thrust curve formats - Showing events in plots - Table boolean selecting by clicking label +- Test automatic exception reporting (for 0.9.3) +- Draw remaining event icons (for 0.9.3) +- Update "About" dialog with icon and source info diff --git a/build.properties b/build.properties index a4010f5ad..4bf3b9e31 100644 --- a/build.properties +++ b/build.properties @@ -1,8 +1,12 @@ # The OpenRocket build version + build.version=0.9.3pre + # The source of the package. When building a package for a specific # distribution (Debian, Fedora etc.), this should be changed appropriately! +# This is displayed in the About dialog and included in bug reports. + build.source=default diff --git a/pix-src/eventicons/event-ejection-charge.xcf.gz b/pix-src/eventicons/event-ejection-charge.xcf.gz new file mode 100644 index 000000000..206593ed8 Binary files /dev/null and b/pix-src/eventicons/event-ejection-charge.xcf.gz differ diff --git a/pix-src/eventicons/event-ground-hit.xcf.gz b/pix-src/eventicons/event-ground-hit.xcf.gz new file mode 100644 index 000000000..cbce15f89 Binary files /dev/null and b/pix-src/eventicons/event-ground-hit.xcf.gz differ diff --git a/pix-src/eventicons/event-launch.xcf.gz b/pix-src/eventicons/event-launch.xcf.gz new file mode 100644 index 000000000..a356787df Binary files /dev/null and b/pix-src/eventicons/event-launch.xcf.gz differ diff --git a/pix-src/eventicons/event-recovery-device-deployment.xcf.gz b/pix-src/eventicons/event-recovery-device-deployment.xcf.gz new file mode 100644 index 000000000..c33abef4b Binary files /dev/null and b/pix-src/eventicons/event-recovery-device-deployment.xcf.gz differ diff --git a/pix/eventicons/copyright.txt b/pix/eventicons/copyright.txt index 9fa8d1b00..50170ef5b 100644 --- a/pix/eventicons/copyright.txt +++ b/pix/eventicons/copyright.txt @@ -1,5 +1,6 @@ +event-simulation-end.png from famfamfam Silk icon set +(http://www.famfamfam.com/lab/icons/silk/) + -event-simulation-end.png from famfamfam icon set - -All others custom-drawn. +All others custom-drawn by Sampo Niskanen. diff --git a/pix/eventicons/event-ejection-charge.png b/pix/eventicons/event-ejection-charge.png new file mode 100644 index 000000000..d58eb8e12 Binary files /dev/null and b/pix/eventicons/event-ejection-charge.png differ diff --git a/pix/eventicons/event-ground-hit.png b/pix/eventicons/event-ground-hit.png new file mode 100644 index 000000000..583e402ac Binary files /dev/null and b/pix/eventicons/event-ground-hit.png differ diff --git a/pix/eventicons/event-launch.png b/pix/eventicons/event-launch.png new file mode 100644 index 000000000..85d714dfe Binary files /dev/null and b/pix/eventicons/event-launch.png differ diff --git a/pix/eventicons/event-recovery-device-deployment.png b/pix/eventicons/event-recovery-device-deployment.png new file mode 100644 index 000000000..df701c144 Binary files /dev/null and b/pix/eventicons/event-recovery-device-deployment.png differ diff --git a/pix/icon/icon-about.png b/pix/icon/icon-about.png new file mode 100644 index 000000000..0ce17f774 Binary files /dev/null and b/pix/icon/icon-about.png differ diff --git a/src/net/sf/openrocket/aerodynamics/AerodynamicCalculator.java b/src/net/sf/openrocket/aerodynamics/AerodynamicCalculator.java index efdd14b15..35d53a185 100644 --- a/src/net/sf/openrocket/aerodynamics/AerodynamicCalculator.java +++ b/src/net/sf/openrocket/aerodynamics/AerodynamicCalculator.java @@ -5,8 +5,8 @@ import static net.sf.openrocket.util.MathUtil.pow2; import java.util.Iterator; import java.util.Map; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.Configuration; -import net.sf.openrocket.rocketcomponent.Motor; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; diff --git a/src/net/sf/openrocket/database/Databases.java b/src/net/sf/openrocket/database/Databases.java index 3f4d8e20f..f3fa4bcf9 100644 --- a/src/net/sf/openrocket/database/Databases.java +++ b/src/net/sf/openrocket/database/Databases.java @@ -8,7 +8,7 @@ import java.util.ArrayList; import net.sf.openrocket.file.GeneralMotorLoader; import net.sf.openrocket.material.Material; import net.sf.openrocket.material.MaterialStorage; -import net.sf.openrocket.rocketcomponent.Motor; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.util.JarUtil; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.Prefs; @@ -229,7 +229,7 @@ public class Databases { boolean match = true; if (type != null && type != m.getMotorType()) match = false; - else if (manufacturer != null && !manufacturer.equalsIgnoreCase(m.getManufacturer())) + else if (manufacturer != null && !m.getManufacturer().matches(manufacturer)) match = false; else if (designation != null && !designation.equalsIgnoreCase(m.getDesignation())) match = false; diff --git a/src/net/sf/openrocket/file/GeneralMotorLoader.java b/src/net/sf/openrocket/file/GeneralMotorLoader.java index cd4ec007e..5981c2d08 100644 --- a/src/net/sf/openrocket/file/GeneralMotorLoader.java +++ b/src/net/sf/openrocket/file/GeneralMotorLoader.java @@ -6,7 +6,7 @@ import java.io.Reader; import java.nio.charset.Charset; import java.util.List; -import net.sf.openrocket.rocketcomponent.Motor; +import net.sf.openrocket.motor.Motor; /** * A motor loader class that detects the file type based on the file name extension. diff --git a/src/net/sf/openrocket/file/MotorLoader.java b/src/net/sf/openrocket/file/MotorLoader.java index 2988a03e8..004b14f13 100644 --- a/src/net/sf/openrocket/file/MotorLoader.java +++ b/src/net/sf/openrocket/file/MotorLoader.java @@ -8,174 +8,15 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import net.sf.openrocket.rocketcomponent.Motor; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.util.MathUtil; public abstract class MotorLoader implements Loader { - /** - * Manufacturer codes to expand. These are general translations that are used - * both in RASP and RockSim engine files. - */ - private static final Map MANUFACTURER_CODES = - new HashMap(); - static { - - /* - * TODO: CRITICAL: Should names have Inc. LLC. etc? - */ - - // AeroTech has many name combinations... - for (String s: new String[] { "A", "AT", "AERO", "AEROT", "AEROTECH" }) { - MANUFACTURER_CODES.put(s, "AeroTech"); - MANUFACTURER_CODES.put(s+"-RMS", "AeroTech"); - MANUFACTURER_CODES.put(s+"/RMS", "AeroTech"); - MANUFACTURER_CODES.put(s+"-RCS", "AeroTech"); - MANUFACTURER_CODES.put(s+"/RCS", "AeroTech"); - MANUFACTURER_CODES.put("RCS-" + s, "AeroTech"); - MANUFACTURER_CODES.put("RCS/" + s, "AeroTech"); - MANUFACTURER_CODES.put(s+"-APOGEE", "AeroTech"); - MANUFACTURER_CODES.put(s+"/APOGEE", "AeroTech"); - } - MANUFACTURER_CODES.put("ISP", "AeroTech"); - - MANUFACTURER_CODES.put("AHR", "Alpha Hybrid Rocketry LLC"); - MANUFACTURER_CODES.put("ALPHA", "Alpha Hybrid Rocketry LLC"); - MANUFACTURER_CODES.put("ALPHA HYBRID", "Alpha Hybrid Rocketry LLC"); - MANUFACTURER_CODES.put("ALPHA HYBRIDS", "Alpha Hybrid Rocketry LLC"); - MANUFACTURER_CODES.put("ALPHA HYBRID ROCKETRY", "Alpha Hybrid Rocketry LLC"); - MANUFACTURER_CODES.put("ALPHA HYBRIDS ROCKETRY", "Alpha Hybrid Rocketry LLC"); - MANUFACTURER_CODES.put("ALPHA HYBRID ROCKETRY LLC", "Alpha Hybrid Rocketry LLC"); - MANUFACTURER_CODES.put("ALPHA HYBRID ROCKETRY, LLC", "Alpha Hybrid Rocketry LLC"); - - MANUFACTURER_CODES.put("AMW", "Animal Motor Works"); - MANUFACTURER_CODES.put("AW", "Animal Motor Works"); - MANUFACTURER_CODES.put("ANIMAL", "Animal Motor Works"); - MANUFACTURER_CODES.put("ANIMAL MOTOR WORKS", "Animal Motor Works"); - - MANUFACTURER_CODES.put("AP", "Apogee"); - MANUFACTURER_CODES.put("APOG", "Apogee"); - MANUFACTURER_CODES.put("APOGEE", "Apogee"); - MANUFACTURER_CODES.put("P", "Apogee"); - - MANUFACTURER_CODES.put("CES", "Cesaroni Technology Inc."); - MANUFACTURER_CODES.put("CESARONI", "Cesaroni Technology Inc."); - MANUFACTURER_CODES.put("CESARONI TECHNOLOGY", "Cesaroni Technology Inc."); - MANUFACTURER_CODES.put("CESARONI TECHNOLOGY INC", "Cesaroni Technology Inc."); - MANUFACTURER_CODES.put("CESARONI TECHNOLOGY INC.", "Cesaroni Technology Inc."); - MANUFACTURER_CODES.put("CESARONI TECHNOLOGY INCORPORATED", "Cesaroni Technology Inc."); - MANUFACTURER_CODES.put("CTI", "Cesaroni Technology Inc."); - MANUFACTURER_CODES.put("CS", "Cesaroni Technology Inc."); - MANUFACTURER_CODES.put("CSR", "Cesaroni Technology Inc."); - MANUFACTURER_CODES.put("PRO38", "Cesaroni Technology Inc."); - - MANUFACTURER_CODES.put("CR", "Contrail Rockets"); - MANUFACTURER_CODES.put("CONTR", "Contrail Rockets"); - MANUFACTURER_CODES.put("CONTRAIL", "Contrail Rockets"); - MANUFACTURER_CODES.put("CONTRAIL ROCKET", "Contrail Rockets"); - MANUFACTURER_CODES.put("CONTRAIL ROCKETS", "Contrail Rockets"); - - MANUFACTURER_CODES.put("E", "Estes"); - MANUFACTURER_CODES.put("ES", "Estes"); - MANUFACTURER_CODES.put("ESTES", "Estes"); - - MANUFACTURER_CODES.put("EM", "Ellis Mountain"); - MANUFACTURER_CODES.put("ELLIS", "Ellis Mountain"); - MANUFACTURER_CODES.put("ELLIS MOUNTAIN", "Ellis Mountain"); - MANUFACTURER_CODES.put("ELLIS MOUNTAIN ROCKET", "Ellis Mountain"); - MANUFACTURER_CODES.put("ELLIS MOUNTAIN ROCKETS", "Ellis Mountain"); - - MANUFACTURER_CODES.put("GR", "Gorilla Rocket Motors"); - MANUFACTURER_CODES.put("GORILLA", "Gorilla Rocket Motors"); - MANUFACTURER_CODES.put("GORILLA ROCKET", "Gorilla Rocket Motors"); - MANUFACTURER_CODES.put("GORILLA ROCKETS", "Gorilla Rocket Motors"); - MANUFACTURER_CODES.put("GORILLA MOTOR", "Gorilla Rocket Motors"); - MANUFACTURER_CODES.put("GORILLA MOTORS", "Gorilla Rocket Motors"); - MANUFACTURER_CODES.put("GORILLA ROCKET MOTOR", "Gorilla Rocket Motors"); - MANUFACTURER_CODES.put("GORILLA ROCKET MOTORS", "Gorilla Rocket Motors"); - - MANUFACTURER_CODES.put("H", "HyperTEK"); - MANUFACTURER_CODES.put("HT", "HyperTEK"); - MANUFACTURER_CODES.put("HYPER", "HyperTEK"); - MANUFACTURER_CODES.put("HYPERTEK", "HyperTEK"); - - MANUFACTURER_CODES.put("K", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("KBA", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("K/AT", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("K-AT", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("KOS", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("KOSDON", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("KOSDON/AT", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("KOSDON-AT", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("KOSDON/AEROTECH", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("KOSDON-AEROTECH", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("KOSDON-BY-AEROTECH", "Kosdon by AeroTech"); - MANUFACTURER_CODES.put("KOSDON BY AEROTECH", "Kosdon by AeroTech"); - - MANUFACTURER_CODES.put("LOKI", "Loki Research"); - MANUFACTURER_CODES.put("LOKI RESEARCH", "Loki Research"); - MANUFACTURER_CODES.put("LR", "Loki Research"); - - MANUFACTURER_CODES.put("PM", "Public Missiles, Ltd."); - MANUFACTURER_CODES.put("PML", "Public Missiles, Ltd."); - MANUFACTURER_CODES.put("PUBLIC MISSILES", "Public Missiles, Ltd."); - MANUFACTURER_CODES.put("PUBLIC MISSILES LTD", "Public Missiles, Ltd."); - MANUFACTURER_CODES.put("PUBLIC MISSILES, LTD", "Public Missiles, Ltd."); - MANUFACTURER_CODES.put("PUBLIC MISSILES LTD.", "Public Missiles, Ltd."); - MANUFACTURER_CODES.put("PUBLIC MISSILES, LTD.", "Public Missiles, Ltd."); - MANUFACTURER_CODES.put("PUBLIC MISSILES LIMITED", "Public Missiles, Ltd."); - MANUFACTURER_CODES.put("PUBLIC MISSILES, LIMITED", "Public Missiles, Ltd."); - - MANUFACTURER_CODES.put("PP", "Propulsion Polymers"); - MANUFACTURER_CODES.put("PROP", "Propulsion Polymers"); - MANUFACTURER_CODES.put("PROPULSION", "Propulsion Polymers"); - MANUFACTURER_CODES.put("PROPULSION-POLYMERS", "Propulsion Polymers"); - MANUFACTURER_CODES.put("PROPULSION POLYMERS", "Propulsion Polymers"); - - MANUFACTURER_CODES.put("Q", "Quest"); - MANUFACTURER_CODES.put("QU", "Quest"); - MANUFACTURER_CODES.put("QUEST", "Quest"); - - MANUFACTURER_CODES.put("RATT", "RATT Works"); - MANUFACTURER_CODES.put("RATT WORKS", "RATT Works"); - MANUFACTURER_CODES.put("RT", "RATT Works"); - MANUFACTURER_CODES.put("RTW", "RATT Works"); - - MANUFACTURER_CODES.put("RR", "Roadrunner Rocketry"); - MANUFACTURER_CODES.put("ROADRUNNER", "Roadrunner Rocketry"); - MANUFACTURER_CODES.put("ROADRUNNER ROCKETRY", "Roadrunner Rocketry"); - - MANUFACTURER_CODES.put("RV", "Rocketvision"); - MANUFACTURER_CODES.put("ROCKETVISION", "Rocketvision"); - - MANUFACTURER_CODES.put("SR", "Sky Ripper Systems"); - MANUFACTURER_CODES.put("SRS", "Sky Ripper Systems"); - MANUFACTURER_CODES.put("SKYR", "Sky Ripper Systems"); - MANUFACTURER_CODES.put("SKYRIPPER", "Sky Ripper Systems"); - MANUFACTURER_CODES.put("SKYRIPPER SYSTEMS", "Sky Ripper Systems"); - MANUFACTURER_CODES.put("SKY RIPPER SYSTEMS", "Sky Ripper Systems"); - - MANUFACTURER_CODES.put("WCH", "West Coast Hybrids"); - MANUFACTURER_CODES.put("WCR", "West Coast Hybrids"); - MANUFACTURER_CODES.put("WEST COAST HYBRIDS", "West Coast Hybrids"); - - MANUFACTURER_CODES.put("SF", "WECO Feuerwerk"); // Previously Sachsen Feuerwerks - MANUFACTURER_CODES.put("SACHSEN FEUERWERK", "WECO Feuerwerk"); - MANUFACTURER_CODES.put("SACHSEN FEUERWERKS", "WECO Feuerwerk"); - MANUFACTURER_CODES.put("WECO", "WECO Feuerwerk"); - MANUFACTURER_CODES.put("WECO FEUERWERK", "WECO Feuerwerk"); - MANUFACTURER_CODES.put("WECO FEUERWERKS", "WECO Feuerwerk"); - } - - - - /** * Load motors from the specified InputStream. The file is read using * the default charset returned by {@link #getDefaultCharset()}. @@ -330,28 +171,7 @@ public abstract class MotorLoader implements Loader { } while (index < primary.size()-1); } - - /** - * Convert a manufacturer string. This should be done for all manufacturers - * for overall consistency. This includes both RASP name expansions and some - * general renaming. This should also be performed when loading designs in order - * to identify manufacturers correctly. - * - * @param mfg the original manufacturer / manufacturer code. - * @return the manufacturer name. - */ - public static String convertManufacturer(String mfg) { - // Replace underscore and trim - mfg = mfg.replace('_', ' ').trim(); - - // Check for conversion - String conv = MANUFACTURER_CODES.get(mfg.toUpperCase()); - if (conv != null) - return conv; - else - return mfg; - } - + @SuppressWarnings("unchecked") protected static void finalizeThrustCurve(List time, List thrust, diff --git a/src/net/sf/openrocket/file/OpenRocketLoader.java b/src/net/sf/openrocket/file/OpenRocketLoader.java index f7b270fce..1d33fd18f 100644 --- a/src/net/sf/openrocket/file/OpenRocketLoader.java +++ b/src/net/sf/openrocket/file/OpenRocketLoader.java @@ -20,6 +20,7 @@ import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; import net.sf.openrocket.file.simplesax.SimpleSAX; import net.sf.openrocket.material.Material; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.BodyComponent; import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.Bulkhead; @@ -37,7 +38,6 @@ import net.sf.openrocket.rocketcomponent.InternalComponent; import net.sf.openrocket.rocketcomponent.LaunchLug; import net.sf.openrocket.rocketcomponent.MassComponent; import net.sf.openrocket.rocketcomponent.MassObject; -import net.sf.openrocket.rocketcomponent.Motor; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.NoseCone; import net.sf.openrocket.rocketcomponent.Parachute; @@ -1030,7 +1030,7 @@ class MotorHandler extends ElementHandler { } else if (element.equals("manufacturer")) { // Manufacturer - manufacturer = MotorLoader.convertManufacturer(content); + manufacturer = content; } else if (element.equals("designation")) { diff --git a/src/net/sf/openrocket/file/RASPMotorLoader.java b/src/net/sf/openrocket/file/RASPMotorLoader.java index 4de798256..558e7cd8e 100644 --- a/src/net/sf/openrocket/file/RASPMotorLoader.java +++ b/src/net/sf/openrocket/file/RASPMotorLoader.java @@ -8,8 +8,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import net.sf.openrocket.rocketcomponent.Motor; -import net.sf.openrocket.rocketcomponent.ThrustCurveMotor; +import net.sf.openrocket.motor.Manufacturer; +import net.sf.openrocket.motor.Motor; +import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.util.Coordinate; public class RASPMotorLoader extends MotorLoader { @@ -118,7 +119,7 @@ public class RASPMotorLoader extends MotorLoader { propW = Double.parseDouble(pieces[4]); totalW = Double.parseDouble(pieces[5]); - manufacturer = convertManufacturer(pieces[6]); + manufacturer = pieces[6]; if (propW > totalW) { throw new IOException("Propellant weight exceeds total weight in " + @@ -196,7 +197,8 @@ public class RASPMotorLoader extends MotorLoader { try { - return new ThrustCurveMotor(manufacturer, designation, comment, Motor.Type.UNKNOWN, + return new ThrustCurveMotor(Manufacturer.getManufacturer(manufacturer), + designation, comment, Motor.Type.UNKNOWN, delays, diameter, length, timeArray, thrustArray, cgArray); } catch (IllegalArgumentException e) { diff --git a/src/net/sf/openrocket/file/RockSimMotorLoader.java b/src/net/sf/openrocket/file/RockSimMotorLoader.java index eef74ac96..b39a9218e 100644 --- a/src/net/sf/openrocket/file/RockSimMotorLoader.java +++ b/src/net/sf/openrocket/file/RockSimMotorLoader.java @@ -12,8 +12,9 @@ import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.NullElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; import net.sf.openrocket.file.simplesax.SimpleSAX; -import net.sf.openrocket.rocketcomponent.Motor; -import net.sf.openrocket.rocketcomponent.ThrustCurveMotor; +import net.sf.openrocket.motor.Manufacturer; +import net.sf.openrocket.motor.Motor; +import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.util.Coordinate; import org.xml.sax.InputSource; @@ -147,7 +148,7 @@ public class RockSimMotorLoader extends MotorLoader { str = attributes.get("mfg"); if (str == null) throw new SAXException("Manufacturer missing"); - manufacturer = convertManufacturer(str); + manufacturer = str; // Designation str = attributes.get("code"); @@ -339,7 +340,8 @@ public class RockSimMotorLoader extends MotorLoader { } try { - return new ThrustCurveMotor(manufacturer, designation, description, type, + return new ThrustCurveMotor(Manufacturer.getManufacturer(manufacturer), + designation, description, type, delays, diameter, length, timeArray, thrustArray, cgArray); } catch (IllegalArgumentException e) { throw new SAXException("Illegal motor data", e); diff --git a/src/net/sf/openrocket/file/openrocket/RocketComponentSaver.java b/src/net/sf/openrocket/file/openrocket/RocketComponentSaver.java index 1a1a3156b..a9da9b2fd 100644 --- a/src/net/sf/openrocket/file/openrocket/RocketComponentSaver.java +++ b/src/net/sf/openrocket/file/openrocket/RocketComponentSaver.java @@ -7,8 +7,8 @@ import java.util.List; import net.sf.openrocket.file.RocketSaver; import net.sf.openrocket.material.Material; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.ComponentAssembly; -import net.sf.openrocket.rocketcomponent.Motor; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; @@ -121,7 +121,7 @@ public class RocketComponentSaver { if (motor.getMotorType() != Motor.Type.UNKNOWN) { elements.add(" " + motor.getMotorType().name().toLowerCase() + ""); } - elements.add(" " + RocketSaver.escapeXML(motor.getManufacturer()) + ""); + elements.add(" " + RocketSaver.escapeXML(motor.getManufacturer().getSimpleName()) + ""); elements.add(" " + RocketSaver.escapeXML(motor.getDesignation()) + ""); elements.add(" " + motor.getDiameter() + ""); elements.add(" " + motor.getLength() + ""); diff --git a/src/net/sf/openrocket/gui/configdialog/MotorConfig.java b/src/net/sf/openrocket/gui/configdialog/MotorConfig.java index 7e0afef34..c4210e6c2 100644 --- a/src/net/sf/openrocket/gui/configdialog/MotorConfig.java +++ b/src/net/sf/openrocket/gui/configdialog/MotorConfig.java @@ -25,8 +25,8 @@ 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.dialogs.MotorChooserDialog; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.Configuration; -import net.sf.openrocket.rocketcomponent.Motor; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; @@ -186,7 +186,7 @@ public class MotorConfig extends JPanel { if (m == null) motorLabel.setText("None"); else - motorLabel.setText(m.getManufacturer() + " " + + motorLabel.setText(m.getManufacturer().getDisplayName() + " " + m.getDesignation(mount.getMotorDelay(id))); } diff --git a/src/net/sf/openrocket/gui/dialogs/AboutDialog.java b/src/net/sf/openrocket/gui/dialogs/AboutDialog.java index 3cc99f5cf..3b151f709 100644 --- a/src/net/sf/openrocket/gui/dialogs/AboutDialog.java +++ b/src/net/sf/openrocket/gui/dialogs/AboutDialog.java @@ -6,12 +6,14 @@ import java.awt.event.ActionListener; 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.components.ResizeLabel; import net.sf.openrocket.gui.components.URLLabel; import net.sf.openrocket.util.GUIUtil; +import net.sf.openrocket.util.Icons; import net.sf.openrocket.util.Prefs; public class AboutDialog extends JDialog { @@ -26,12 +28,24 @@ public class AboutDialog extends JDialog { JPanel panel = new JPanel(new MigLayout("fill")); - panel.add(new ResizeLabel("OpenRocket", 20), "ax 50%, wrap para"); - panel.add(new ResizeLabel("Version " + version, 3), "ax 50%, wrap 30lp"); + panel.add(new JLabel(Icons.loadImageIcon("pix/icon/icon-about.png", "OpenRocket")), + "spany 5, top"); - panel.add(new ResizeLabel("Copyright \u00A9 2007-2009 Sampo Niskanen"), "ax 50%, wrap para"); + panel.add(new ResizeLabel("OpenRocket", 20), "ax 50%, growy, wrap para"); + panel.add(new ResizeLabel("Version " + version, 3), "ax 50%, growy, wrap rel"); - panel.add(new URLLabel(OPENROCKET_URL), "ax 50%, wrap para"); + String source = Prefs.getBuildSource(); + if (!Prefs.DEFAULT_BUILD_SOURCE.equalsIgnoreCase(source)) { + panel.add(new ResizeLabel("Distributed by " + source, -1), + "ax 50%, growy, wrap para"); + } else { + panel.add(new ResizeLabel(" ", -1), "ax 50%, growy, wrap para"); + } + + panel.add(new ResizeLabel("Copyright \u00A9 2007-2009 Sampo Niskanen"), + "ax 50%, growy, wrap para"); + + panel.add(new URLLabel(OPENROCKET_URL), "ax 50%, growy, wrap para"); JButton close = new JButton("Close"); @@ -41,7 +55,7 @@ public class AboutDialog extends JDialog { AboutDialog.this.dispose(); } }); - panel.add(close, "right"); + panel.add(close, "spanx, right"); this.add(panel); this.setTitle("OpenRocket " + version); diff --git a/src/net/sf/openrocket/gui/dialogs/BugReportDialog.java b/src/net/sf/openrocket/gui/dialogs/BugReportDialog.java index add913274..b58d48a35 100644 --- a/src/net/sf/openrocket/gui/dialogs/BugReportDialog.java +++ b/src/net/sf/openrocket/gui/dialogs/BugReportDialog.java @@ -143,7 +143,7 @@ public class BugReportDialog extends JDialog { this.pack(); this.setLocationRelativeTo(parent); GUIUtil.installEscapeCloseOperation(this); -// GUIUtil.setDefaultButton(close); + GUIUtil.setDefaultButton(send); } diff --git a/src/net/sf/openrocket/gui/dialogs/EditMotorConfigurationDialog.java b/src/net/sf/openrocket/gui/dialogs/EditMotorConfigurationDialog.java index e554c4132..a42d8a944 100644 --- a/src/net/sf/openrocket/gui/dialogs/EditMotorConfigurationDialog.java +++ b/src/net/sf/openrocket/gui/dialogs/EditMotorConfigurationDialog.java @@ -27,7 +27,7 @@ import javax.swing.table.TableColumnModel; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.main.BasicFrame; -import net.sf.openrocket.rocketcomponent.Motor; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; diff --git a/src/net/sf/openrocket/gui/dialogs/MotorChooserDialog.java b/src/net/sf/openrocket/gui/dialogs/MotorChooserDialog.java index 3a5a154ca..95b2aad6d 100644 --- a/src/net/sf/openrocket/gui/dialogs/MotorChooserDialog.java +++ b/src/net/sf/openrocket/gui/dialogs/MotorChooserDialog.java @@ -38,7 +38,7 @@ import javax.swing.table.TableRowSorter; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.database.Databases; import net.sf.openrocket.gui.components.ResizeLabel; -import net.sf.openrocket.rocketcomponent.Motor; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.util.GUIUtil; import net.sf.openrocket.util.Prefs; @@ -382,7 +382,7 @@ public class MotorChooserDialog extends JDialog { MANUFACTURER("Manufacturer",100) { @Override public String getValue(Motor m) { - return m.getManufacturer(); + return m.getManufacturer().getDisplayName(); } // @Override // public String getToolTipText(Motor m) { diff --git a/src/net/sf/openrocket/gui/plot/PlotDialog.java b/src/net/sf/openrocket/gui/plot/PlotDialog.java index 0b8c4acd2..a40c841a2 100644 --- a/src/net/sf/openrocket/gui/plot/PlotDialog.java +++ b/src/net/sf/openrocket/gui/plot/PlotDialog.java @@ -81,16 +81,18 @@ public class PlotDialog extends JDialog { private static final Map EVENT_IMAGES = new HashMap(); static { - loadImage(FlightEvent.Type.LAUNCH, "pix/spheres/red-16x16.png"); + loadImage(FlightEvent.Type.LAUNCH, "pix/eventicons/event-launch.png"); loadImage(FlightEvent.Type.LIFTOFF, "pix/eventicons/event-liftoff.png"); loadImage(FlightEvent.Type.LAUNCHROD, "pix/eventicons/event-launchrod.png"); loadImage(FlightEvent.Type.IGNITION, "pix/eventicons/event-ignition.png"); loadImage(FlightEvent.Type.BURNOUT, "pix/eventicons/event-burnout.png"); - loadImage(FlightEvent.Type.EJECTION_CHARGE, "pix/spheres/green-16x16.png"); - loadImage(FlightEvent.Type.STAGE_SEPARATION, "pix/eventicons/event-stage-separation.png"); + loadImage(FlightEvent.Type.EJECTION_CHARGE,"pix/eventicons/event-ejection-charge.png"); + loadImage(FlightEvent.Type.STAGE_SEPARATION, + "pix/eventicons/event-stage-separation.png"); loadImage(FlightEvent.Type.APOGEE, "pix/eventicons/event-apogee.png"); - loadImage(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT, "pix/spheres/blue-16x16.png"); - loadImage(FlightEvent.Type.GROUND_HIT, "pix/spheres/gray-16x16.png"); + loadImage(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT, + "pix/eventicons/event-recovery-device-deployment.png"); + loadImage(FlightEvent.Type.GROUND_HIT, "pix/eventicons/event-ground-hit.png"); loadImage(FlightEvent.Type.SIMULATION_END, "pix/eventicons/event-simulation-end.png"); } diff --git a/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index f6d7d9de7..35158def5 100644 --- a/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -20,8 +20,8 @@ import java.util.Iterator; import java.util.LinkedHashSet; import net.sf.openrocket.gui.figureelements.FigureElement; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.Configuration; -import net.sf.openrocket.rocketcomponent.Motor; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.util.Coordinate; diff --git a/src/net/sf/openrocket/motor/Manufacturer.java b/src/net/sf/openrocket/motor/Manufacturer.java new file mode 100644 index 000000000..3e7365bea --- /dev/null +++ b/src/net/sf/openrocket/motor/Manufacturer.java @@ -0,0 +1,226 @@ +package net.sf.openrocket.motor; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class Manufacturer { + + private static Set manufacturers = new HashSet(); + static { + + // AeroTech has many name combinations... + List names = new ArrayList(); + for (String s: new String[] { "A", "AT", "AERO", "AEROT", "AEROTECH" }) { + names.add(s); + names.add(s+"-RMS"); + names.add(s+"-RCS"); + names.add("RCS-" + s); + names.add(s+"-APOGEE"); + } + names.add("ISP"); + + manufacturers.add(new Manufacturer("AeroTech", "AeroTech", + names.toArray(new String[0]))); + + manufacturers.add(new Manufacturer("Alpha Hybrid Rocketry LLC", + "Alpha Hybrid Rocketry", + "AHR", "ALPHA", "ALPHA HYBRID", "ALPHA HYBRIDS", "ALPHA HYBRIDS ROCKETRY")); + + manufacturers.add(new Manufacturer("Animal Motor Works","Animal Motor Works", + "AMW", "AW", "ANIMAL")); + + manufacturers.add(new Manufacturer("Apogee","Apogee", + "AP", "APOG", "P")); + + manufacturers.add(new Manufacturer("Cesaroni Technology Inc.", + "Cesaroni Technology", + "CES", "CESARONI", "CESARONI TECHNOLOGY INCORPORATED", "CTI", + "CS", "CSR", "PRO38")); + + manufacturers.add(new Manufacturer("Contrail Rockets","Contrail Rockets", + "CR", "CONTR", "CONTRAIL", "CONTRAIL ROCKET")); + + manufacturers.add(new Manufacturer("Estes","Estes", + "E", "ES")); + + manufacturers.add(new Manufacturer("Ellis Mountain","Ellis Mountain", + "EM", "ELLIS", "ELLIS MOUNTAIN ROCKET", "ELLIS MOUNTAIN ROCKETS")); + + manufacturers.add(new Manufacturer("Gorilla Rocket Motors", + "Gorilla Rocket Motors", + "GR", "GORILLA", "GORILLA ROCKET", "GORILLA ROCKETS", "GORILLA MOTOR", + "GORILLA MOTORS", "GORILLA ROCKET MOTOR")); + + manufacturers.add(new Manufacturer("HyperTEK", "HyperTEK", + "H", "HT", "HYPER")); + + manufacturers.add(new Manufacturer("Kosdon by AeroTech", "Kosdon by AeroTech", + "K", "KBA", "K-AT", "KOS", "KOSDON", "KOSDON/AT", "KOSDON/AEROTECH")); + + manufacturers.add(new Manufacturer("Loki Research", "Loki Research", + "LOKI", "LR")); + + manufacturers.add(new Manufacturer("Public Missiles, Ltd.", "Public Missiles", + "PM", "PML", "PUBLIC MISSILES LIMITED")); + + manufacturers.add(new Manufacturer("Propulsion Polymers", "Propulsion Polymers", + "PP", "PROP", "PROPULSION")); + + manufacturers.add(new Manufacturer("Quest", "Quest", + "Q", "QU")); + + manufacturers.add(new Manufacturer("RATT Works", "RATT Works", + "RATT", "RT", "RTW")); + + manufacturers.add(new Manufacturer("Roadrunner Rocketry","Roadrunner Rocketry", + "RR", "ROADRUNNER")); + + manufacturers.add(new Manufacturer("Rocketvision", "Rocketvision", + "RV", "ROCKET VISION")); + + manufacturers.add(new Manufacturer("Sky Ripper Systems","Sky Ripper Systems", + "SR", "SRS", "SKYR", "SKYRIPPER", "SKY RIPPER", "SKYRIPPER SYSTEMS")); + + manufacturers.add(new Manufacturer("West Coast Hybrids", "West Coast Hybrids", + "WCH", "WCR", "WEST COAST", "WEST COAST HYBRID")); + + // German WECO Feuerwerk, previously Sachsen Feuerwerk + manufacturers.add(new Manufacturer("WECO Feuerwerk", "WECO Feuerwerk", + "WECO", "WECO FEUERWERKS", "SF", "SACHSEN", "SACHSEN FEUERWERK", + "SACHSEN FEUERWERKS")); + + + // Check that no duplicates have appeared + for (Manufacturer m1: manufacturers) { + for (Manufacturer m2: manufacturers) { + if (m1 == m2) + continue; + for (String name: m1.getAllNames()) { + if (m2.matches(name)) { + throw new IllegalStateException("Manufacturer name clash between " + + "manufacturers " + m1 + " and " + m2 + " name " + name); + } + } + } + } + } + + + + private final String displayName; + private final String simpleName; + private final Set allNames; + private final Set searchNames; + + + private Manufacturer(String displayName, String simpleName, String... alternateNames) { + this.displayName = displayName; + this.simpleName = simpleName; + + Set all = new HashSet(); + Set search = new HashSet(); + + all.add(displayName); + all.add(simpleName); + search.add(generateSearchString(displayName)); + search.add(generateSearchString(simpleName)); + + for (String name: alternateNames) { + all.add(name); + search.add(generateSearchString(name)); + } + + this.allNames = Collections.unmodifiableSet(all); + this.searchNames = Collections.unmodifiableSet(search); + } + + + /** + * Returns the display name of the manufacturer. This is the value that + * should be presented in the UI to the user. + * + * @return the display name + */ + public String getDisplayName() { + return displayName; + } + + + /** + * Returns the simple name of the manufacturer. This should be used for example + * when saving the manufacturer for compatibility. + * + * @return the simple name. + */ + public String getSimpleName() { + return simpleName; + } + + + /** + * Return all names of the manufacturer. This includes all kinds of + * codes that correspond to the manufacturer (for example "A" for AeroTech). + * + * @return an unmodifiable set of the alternative names. + */ + public Set getAllNames() { + return allNames; + } + + + /** + * Check whether the display, simple or any of the alternative names matches the + * specified name. Matching is performed case insensitively and ignoring any + * non-letter and non-number characters. + * + * @param name the name to search for. + * @return whether this manufacturer matches the request. + */ + public boolean matches(String name) { + if (name == null) + return false; + return this.searchNames.contains(generateSearchString(name)); + } + + + /** + * Return the display name of the manufacturer. + */ + @Override + public String toString() { + return displayName; + } + + + /** + * Returns a manufacturer for the given name. The manufacturer is searched for + * within the manufacturers and if a match is found the corresponding + * object is returned. If not, a new manufacturer is returned with display and + * simple name the name specified. Subsequent requests for the same (or corresponding) + * manufacturer name will return the same object. + * + * @param name the manufacturer name to search for. + * @return the Manufacturer object corresponding the name. + */ + public static synchronized Manufacturer getManufacturer(String name) { + for (Manufacturer m: manufacturers) { + if (m.matches(name)) + return m; + } + + Manufacturer m = new Manufacturer(name.trim(), name.trim()); + manufacturers.add(m); + return m; + } + + + + + private String generateSearchString(String str) { + return str.toLowerCase().replaceAll("[^a-zA-Z0-9]+", " ").trim(); + } + +} diff --git a/src/net/sf/openrocket/rocketcomponent/Motor.java b/src/net/sf/openrocket/motor/Motor.java similarity index 98% rename from src/net/sf/openrocket/rocketcomponent/Motor.java rename to src/net/sf/openrocket/motor/Motor.java index 3eef45a16..0da9c3b42 100644 --- a/src/net/sf/openrocket/rocketcomponent/Motor.java +++ b/src/net/sf/openrocket/motor/Motor.java @@ -1,4 +1,4 @@ -package net.sf.openrocket.rocketcomponent; +package net.sf.openrocket.motor; import java.text.Collator; import java.util.Comparator; @@ -94,7 +94,7 @@ public abstract class Motor implements Comparable { - private final String manufacturer; + private final Manufacturer manufacturer; private final String designation; private final String description; private final Type motorType; @@ -125,7 +125,7 @@ public abstract class Motor implements Comparable { * @param diameter maximum diameter of the motor * @param length length of the motor */ - protected Motor(String manufacturer, String designation, String description, + protected Motor(Manufacturer manufacturer, String designation, String description, Type type, double[] delays, double diameter, double length) { if (manufacturer == null || designation == null || description == null || @@ -355,7 +355,7 @@ public abstract class Motor implements Comparable { * * @return the manufacturer */ - public String getManufacturer() { + public Manufacturer getManufacturer() { return manufacturer; } @@ -539,7 +539,8 @@ public abstract class Motor implements Comparable { int value; // 1. Manufacturer - value = COLLATOR.compare(this.manufacturer, other.manufacturer); + value = COLLATOR.compare(this.manufacturer.getDisplayName(), + other.manufacturer.getDisplayName()); if (value != 0) return value; diff --git a/src/net/sf/openrocket/rocketcomponent/ThrustCurveMotor.java b/src/net/sf/openrocket/motor/ThrustCurveMotor.java similarity index 96% rename from src/net/sf/openrocket/rocketcomponent/ThrustCurveMotor.java rename to src/net/sf/openrocket/motor/ThrustCurveMotor.java index 9519aa3ea..e495defeb 100644 --- a/src/net/sf/openrocket/rocketcomponent/ThrustCurveMotor.java +++ b/src/net/sf/openrocket/motor/ThrustCurveMotor.java @@ -1,4 +1,4 @@ -package net.sf.openrocket.rocketcomponent; +package net.sf.openrocket.motor; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; @@ -33,7 +33,7 @@ public class ThrustCurveMotor extends Motor { * @param thrust thrust at the time points. * @param cg cg at the time points. */ - public ThrustCurveMotor(String manufacturer, String designation, String description, + public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, Motor.Type type, double[] delays, double diameter, double length, double[] time, double[] thrust, Coordinate[] cg) { super(manufacturer, designation, description, type, delays, diameter, length); diff --git a/src/net/sf/openrocket/rocketcomponent/BodyTube.java b/src/net/sf/openrocket/rocketcomponent/BodyTube.java index d22ab67d3..d3368f1f1 100644 --- a/src/net/sf/openrocket/rocketcomponent/BodyTube.java +++ b/src/net/sf/openrocket/rocketcomponent/BodyTube.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; diff --git a/src/net/sf/openrocket/rocketcomponent/InnerTube.java b/src/net/sf/openrocket/rocketcomponent/InnerTube.java index 7561c21ef..901b5cb60 100644 --- a/src/net/sf/openrocket/rocketcomponent/InnerTube.java +++ b/src/net/sf/openrocket/rocketcomponent/InnerTube.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; diff --git a/src/net/sf/openrocket/rocketcomponent/MotorMount.java b/src/net/sf/openrocket/rocketcomponent/MotorMount.java index b6dbb5fba..20f3c82e9 100644 --- a/src/net/sf/openrocket/rocketcomponent/MotorMount.java +++ b/src/net/sf/openrocket/rocketcomponent/MotorMount.java @@ -1,5 +1,6 @@ package net.sf.openrocket.rocketcomponent; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.simulation.FlightEvent; import net.sf.openrocket.util.ChangeSource; diff --git a/src/net/sf/openrocket/rocketcomponent/Rocket.java b/src/net/sf/openrocket/rocketcomponent/Rocket.java index 48904f892..3bd4dcdab 100644 --- a/src/net/sf/openrocket/rocketcomponent/Rocket.java +++ b/src/net/sf/openrocket/rocketcomponent/Rocket.java @@ -12,6 +12,7 @@ import java.util.UUID; import javax.swing.event.ChangeListener; import javax.swing.event.EventListenerList; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; diff --git a/src/net/sf/openrocket/simulation/FlightSimulator.java b/src/net/sf/openrocket/simulation/FlightSimulator.java index 2b67530ea..163b7ff2a 100644 --- a/src/net/sf/openrocket/simulation/FlightSimulator.java +++ b/src/net/sf/openrocket/simulation/FlightSimulator.java @@ -11,9 +11,9 @@ import net.sf.openrocket.aerodynamics.AtmosphericConditions; import net.sf.openrocket.aerodynamics.AtmosphericModel; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.Clusterable; import net.sf.openrocket.rocketcomponent.Configuration; -import net.sf.openrocket.rocketcomponent.Motor; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RecoveryDevice; import net.sf.openrocket.rocketcomponent.RocketComponent; diff --git a/src/net/sf/openrocket/util/Coordinate.java b/src/net/sf/openrocket/util/Coordinate.java index 5b88f08a6..099074ec3 100644 --- a/src/net/sf/openrocket/util/Coordinate.java +++ b/src/net/sf/openrocket/util/Coordinate.java @@ -10,10 +10,51 @@ import java.io.Serializable; * @author Sampo Niskanen */ public final class Coordinate implements Serializable { + + //////// Debug section + /* + * Debugging info. If openrocket.debug.coordinatecount is defined, a line is + * printed every 1000000 instantiations (or as many as defined). + */ + private static final boolean COUNT_DEBUG; + private static final int COUNT_DIFF; + static { + String str = System.getProperty("openrocket.debug.coordinatecount", null); + int diff = 0; + if (str == null) { + COUNT_DEBUG = false; + COUNT_DIFF = 0; + } else { + COUNT_DEBUG = true; + try { + diff = Integer.parseInt(str); + } catch (NumberFormatException ignore) { } + if (diff < 1000) + diff = 1000000; + COUNT_DIFF = diff; + } + } + + private static int count = 0; + { + // Debug count + if (COUNT_DEBUG) { + count++; + if ((count % COUNT_DIFF) == 0) { + System.out.println("Coordinate instantiated " + count + " times."); + } + } + } + + //////// End debug section + + + + public static final Coordinate NUL = new Coordinate(0,0,0,0); public static final Coordinate NaN = new Coordinate(Double.NaN,Double.NaN, Double.NaN,Double.NaN); - public static final double COMPARISON_DELTA = 0.000001; + public final double x,y,z; public final double weight; @@ -21,15 +62,6 @@ public final class Coordinate implements Serializable { private double length = -1; /* Cached when calculated */ - /* Count and report the number of times a Coordinate is constructed: */ -// private static int count=0; -// { -// count++; -// if ((count % 1000) == 0) { -// System.err.println("Coordinate instantiated "+count+" times"); -// } -// } - public Coordinate() { @@ -52,6 +84,7 @@ public final class Coordinate implements Serializable { this.y = y; this.z = z; this.weight=w; + } @@ -261,31 +294,4 @@ public final class Coordinate implements Serializable { } - - public static void main(String[] arg) { - double a=1.2; - double x; - Coordinate c; - long t1, t2; - - x = 0; - t1 = System.nanoTime(); - for (int i=0; i < 100000000; i++) { - x = x + a; - } - t2 = System.nanoTime(); - System.out.println("Value: "+x); - System.out.println("Plain addition: "+ ((t2-t1+500000)/1000000) + " ms"); - - c = Coordinate.NUL; - t1 = System.nanoTime(); - for (int i=0; i < 100000000; i++) { - c = c.add(a,0,0); - } - t2 = System.nanoTime(); - System.out.println("Value: "+c.x); - System.out.println("Coordinate addition: "+ ((t2-t1+500000)/1000000) + " ms"); - - } - } diff --git a/src/net/sf/openrocket/util/Icons.java b/src/net/sf/openrocket/util/Icons.java index a97487d30..fa2c25e77 100644 --- a/src/net/sf/openrocket/util/Icons.java +++ b/src/net/sf/openrocket/util/Icons.java @@ -57,7 +57,9 @@ public class Icons { public static final Icon DELETE = loadImageIcon("pix/icons/delete.png", "Delete"); - private static ImageIcon loadImageIcon(String file, String name) { + + + public static ImageIcon loadImageIcon(String file, String name) { URL url = ClassLoader.getSystemResource(file); if (url == null) { System.err.println("Resource "+file+" not found! Ignoring..."); diff --git a/src/net/sf/openrocket/util/MathUtil.java b/src/net/sf/openrocket/util/MathUtil.java index a714f8127..a40742cbb 100644 --- a/src/net/sf/openrocket/util/MathUtil.java +++ b/src/net/sf/openrocket/util/MathUtil.java @@ -73,7 +73,7 @@ public class MathUtil { if (equals(toMin, toMax)) return toMin; if (equals(fromMin, fromMax)) { - throw new IllegalArgumentException("from range is singular an to range is not."); + throw new IllegalArgumentException("from range is singular and to range is not."); } return (value - fromMin)/(fromMax-fromMin) * (toMax - toMin) + toMin; } @@ -168,6 +168,16 @@ public class MathUtil { return Math.abs(a-b) < EPSILON*absb; } + + /** + * Return the sign of the number. This corresponds to Math.signum, but ignores + * the special cases of zero and NaN. The value returned for those is arbitrary. + *

+ * This method is about 4 times faster than Math.signum(). + * + * @param x the checked value. + * @return -1.0 if x<0; 1.0 if x>0; otherwise either -1.0 or 1.0. + */ public static double sign(double x) { return (x<0) ? -1.0 : 1.0; } @@ -180,38 +190,4 @@ public class MathUtil { */ - public static void main(String[] arg) { - double nan = Double.NaN; - System.out.println("min(5,6) = " + min(5, 6)); - System.out.println("min(5,nan) = " + min(5, nan)); - System.out.println("min(nan,6) = " + min(nan, 6)); - System.out.println("min(nan,nan) = " + min(nan, nan)); - System.out.println(); - System.out.println("max(5,6) = " + max(5, 6)); - System.out.println("max(5,nan) = " + max(5, nan)); - System.out.println("max(nan,6) = " + max(nan, 6)); - System.out.println("max(nan,nan) = " + max(nan, nan)); - System.out.println(); - System.out.println("min(5,6,7) = " + min(5, 6, 7)); - System.out.println("min(5,6,nan) = " + min(5, 6, nan)); - System.out.println("min(5,nan,7) = " + min(5, nan, 7)); - System.out.println("min(5,nan,nan) = " + min(5, nan, nan)); - System.out.println("min(nan,6,7) = " + min(nan, 6, 7)); - System.out.println("min(nan,6,nan) = " + min(nan, 6, nan)); - System.out.println("min(nan,nan,7) = " + min(nan, nan, 7)); - System.out.println("min(nan,nan,nan) = " + min(nan, nan, nan)); - System.out.println(); - System.out.println("max(5,6,7) = " + max(5, 6, 7)); - System.out.println("max(5,6,nan) = " + max(5, 6, nan)); - System.out.println("max(5,nan,7) = " + max(5, nan, 7)); - System.out.println("max(5,nan,nan) = " + max(5, nan, nan)); - System.out.println("max(nan,6,7) = " + max(nan, 6, 7)); - System.out.println("max(nan,6,nan) = " + max(nan, 6, nan)); - System.out.println("max(nan,nan,7) = " + max(nan, nan, 7)); - System.out.println("max(nan,nan,nan) = " + max(nan, nan, nan)); - System.out.println(); - - - } - } diff --git a/src/net/sf/openrocket/util/Prefs.java b/src/net/sf/openrocket/util/Prefs.java index 0ca273f65..049b54683 100644 --- a/src/net/sf/openrocket/util/Prefs.java +++ b/src/net/sf/openrocket/util/Prefs.java @@ -55,6 +55,7 @@ public class Prefs { private static final String BUILD_VERSION; private static final String BUILD_SOURCE; + public static final String DEFAULT_BUILD_SOURCE = "default"; static { try { diff --git a/src/net/sf/openrocket/util/Rotation2D.java b/src/net/sf/openrocket/util/Rotation2D.java index f8f063e8d..1672a0114 100644 --- a/src/net/sf/openrocket/util/Rotation2D.java +++ b/src/net/sf/openrocket/util/Rotation2D.java @@ -41,18 +41,4 @@ public class Rotation2D { return new Coordinate(cos*c.x + sin*c.y, cos*c.y - sin*c.x, c.z, c.weight); } - - - public static void main(String arg[]) { - Coordinate c = new Coordinate(1,1,1,2.5); - Rotation2D rot = new Rotation2D(Math.PI/4); - - System.out.println("X: "+rot.rotateX(c)); - System.out.println("Y: "+rot.rotateY(c)); - System.out.println("Z: "+rot.rotateZ(c)); - System.out.println("invX: "+rot.invRotateX(c)); - System.out.println("invY: "+rot.invRotateY(c)); - System.out.println("invZ: "+rot.invRotateZ(c)); - } - } diff --git a/src/net/sf/openrocket/util/Test.java b/src/net/sf/openrocket/util/Test.java index 4d150d42d..c0e37c7ac 100644 --- a/src/net/sf/openrocket/util/Test.java +++ b/src/net/sf/openrocket/util/Test.java @@ -2,6 +2,7 @@ package net.sf.openrocket.util; import net.sf.openrocket.database.Databases; import net.sf.openrocket.material.Material; +import net.sf.openrocket.motor.Motor; import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.Bulkhead; import net.sf.openrocket.rocketcomponent.CenteringRing; @@ -10,7 +11,6 @@ import net.sf.openrocket.rocketcomponent.IllegalFinPointException; import net.sf.openrocket.rocketcomponent.InnerTube; import net.sf.openrocket.rocketcomponent.LaunchLug; import net.sf.openrocket.rocketcomponent.MassComponent; -import net.sf.openrocket.rocketcomponent.Motor; import net.sf.openrocket.rocketcomponent.NoseCone; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Stage; diff --git a/src/net/sf/openrocket/util/TextUtil.java b/src/net/sf/openrocket/util/TextUtil.java index fdbf99128..7d2ee8535 100644 --- a/src/net/sf/openrocket/util/TextUtil.java +++ b/src/net/sf/openrocket/util/TextUtil.java @@ -1,16 +1,13 @@ package net.sf.openrocket.util; -import java.util.Locale; public class TextUtil { /** - * Return a string of the double value with suitable precision. + * Return a string of the double value with suitable precision (5 digits). * The string is the shortest representation of the value including the * required precision. * - * TODO: MEDIUM: Extra zeros are added unnecessarily to the end of the string. - * * @param d the value to present. * @return a representation with suitable precision. */ @@ -31,46 +28,106 @@ public class TextUtil { } + final String sign = (d < 0) ? "-" : ""; double abs = Math.abs(d); - if (abs < 0.001) { - // Compact exponential notation - int exp = 0; - - while (abs < 1.0) { - abs *= 10; - exp++; - } - - String sign = (d < 0) ? "-" : ""; - return sign + String.format((Locale)null, "%.4fe-%d", abs, exp); + // Small and large values always in exponential notation + if (abs < 0.001 || abs >= 100000000) { + return sign + exponentialFormat(abs); } - if (abs < 0.01) - return String.format((Locale)null, "%.7f", d); - if (abs < 0.1) - return String.format((Locale)null, "%.6f", d); - if (abs < 1) - return String.format((Locale)null, "%.5f", d); - if (abs < 10) - return String.format((Locale)null, "%.4f", d); - if (abs < 100) - return String.format((Locale)null, "%.3f", d); - if (abs < 1000) - return String.format((Locale)null, "%.2f", d); - if (abs < 10000) - return String.format((Locale)null, "%.1f", d); - if (abs < 100000000.0) - return String.format((Locale)null, "%.0f", d); - - // Compact exponential notation - int exp = 0; - while (abs >= 10.0) { - abs /= 10; + + // Check whether decimal or exponential notation is shorter + + String exp = exponentialFormat(abs); + String dec = decimalFormat(abs); + + if (dec.length() <= exp.length()) + return sign + dec; + else + return sign + exp; + } + + + /* + * value must be positive and not zero! + */ + private static String exponentialFormat(double value) { + int exp; + + exp = 0; + while (value < 1.0) { + value *= 10; + exp--; + } + while (value >= 10.0) { + value /= 10; exp++; } - String sign = (d < 0) ? "-" : ""; - return sign + String.format((Locale)null, "%.4fe%d", abs, exp); + return shortDecimal(value, 4) + "e" + exp; + } + + + /* + * value must be positive and not zero! + */ + private static String decimalFormat(double value) { + if (value >= 10000) + return "" + (int)(value + 0.5); + + int decimals = 1; + double v = value; + while (v < 1000) { + v *= 10; + decimals++; + } + + return shortDecimal(value, decimals); + } + + + + + /* + * value must be positive! + */ + private static String shortDecimal(double value, int decimals) { + + int whole = (int)value; + value -= whole; + + // Calculate limit, return when remaining value less than this + double limit; + limit = 0.5; + for (int i=0; i