Initial i18n support, bug fixes
[debian/openrocket] / src / net / sf / openrocket / gui / plot / PlotDialog.java
index a40c841a21f01c0dcf483282e2c6696142c92acc..b36ff30bf8dd6dd7b416d81fd008b186c85e60a1 100644 (file)
@@ -1,6 +1,7 @@
 package net.sf.openrocket.gui.plot;
 
 import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Composite;
 import java.awt.Font;
@@ -26,17 +27,20 @@ import javax.swing.BorderFactory;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
 import javax.swing.JDialog;
+import javax.swing.JLabel;
 import javax.swing.JPanel;
 
 import net.miginfocom.swing.MigLayout;
 import net.sf.openrocket.document.Simulation;
+import net.sf.openrocket.gui.components.StyledLabel;
 import net.sf.openrocket.simulation.FlightDataBranch;
+import net.sf.openrocket.simulation.FlightDataType;
 import net.sf.openrocket.simulation.FlightEvent;
 import net.sf.openrocket.unit.Unit;
 import net.sf.openrocket.unit.UnitGroup;
+import net.sf.openrocket.util.BugException;
 import net.sf.openrocket.util.GUIUtil;
 import net.sf.openrocket.util.MathUtil;
-import net.sf.openrocket.util.Pair;
 import net.sf.openrocket.util.Prefs;
 
 import org.jfree.chart.ChartFactory;
@@ -61,63 +65,65 @@ import org.jfree.ui.TextAnchor;
 
 public class PlotDialog extends JDialog {
        
-       private static final Color DEFAULT_EVENT_COLOR = new Color(0,0,0);
+       private static final float PLOT_STROKE_WIDTH = 1.5f;
+       
+       private static final Color DEFAULT_EVENT_COLOR = new Color(0, 0, 0);
        private static final Map<FlightEvent.Type, Color> EVENT_COLORS =
-               new HashMap<FlightEvent.Type, Color>();
+                       new HashMap<FlightEvent.Type, Color>();
        static {
-               EVENT_COLORS.put(FlightEvent.Type.LAUNCH, new Color(255,0,0));
-               EVENT_COLORS.put(FlightEvent.Type.LIFTOFF, new Color(0,80,196));
-               EVENT_COLORS.put(FlightEvent.Type.LAUNCHROD, new Color(0,100,80));
-               EVENT_COLORS.put(FlightEvent.Type.IGNITION, new Color(230,130,15));
-               EVENT_COLORS.put(FlightEvent.Type.BURNOUT, new Color(80,55,40));
-               EVENT_COLORS.put(FlightEvent.Type.EJECTION_CHARGE, new Color(80,55,40));
-               EVENT_COLORS.put(FlightEvent.Type.STAGE_SEPARATION, new Color(80,55,40));
-               EVENT_COLORS.put(FlightEvent.Type.APOGEE, new Color(15,120,15));
-               EVENT_COLORS.put(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT, new Color(0,0,128));
-               EVENT_COLORS.put(FlightEvent.Type.GROUND_HIT, new Color(0,0,0));
-               EVENT_COLORS.put(FlightEvent.Type.SIMULATION_END, new Color(128,0,0));
+               EVENT_COLORS.put(FlightEvent.Type.LAUNCH, new Color(255, 0, 0));
+               EVENT_COLORS.put(FlightEvent.Type.LIFTOFF, new Color(0, 80, 196));
+               EVENT_COLORS.put(FlightEvent.Type.LAUNCHROD, new Color(0, 100, 80));
+               EVENT_COLORS.put(FlightEvent.Type.IGNITION, new Color(230, 130, 15));
+               EVENT_COLORS.put(FlightEvent.Type.BURNOUT, new Color(80, 55, 40));
+               EVENT_COLORS.put(FlightEvent.Type.EJECTION_CHARGE, new Color(80, 55, 40));
+               EVENT_COLORS.put(FlightEvent.Type.STAGE_SEPARATION, new Color(80, 55, 40));
+               EVENT_COLORS.put(FlightEvent.Type.APOGEE, new Color(15, 120, 15));
+               EVENT_COLORS.put(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT, new Color(0, 0, 128));
+               EVENT_COLORS.put(FlightEvent.Type.GROUND_HIT, new Color(0, 0, 0));
+               EVENT_COLORS.put(FlightEvent.Type.SIMULATION_END, new Color(128, 0, 0));
        }
-
+       
        private static final Map<FlightEvent.Type, Image> EVENT_IMAGES =
-               new HashMap<FlightEvent.Type, Image>();
+                       new HashMap<FlightEvent.Type, Image>();
        static {
                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/eventicons/event-ejection-charge.png");
-               loadImage(FlightEvent.Type.STAGE_SEPARATION, 
+               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, 
+               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");
        }
+       
+       private static void loadImage(FlightEvent.Type type, String file) {
+               InputStream is;
+               
+               is = ClassLoader.getSystemResourceAsStream(file);
+               if (is == null) {
+                       System.out.println("ERROR: File " + file + " not found!");
+                       return;
+               }
+               
+               try {
+                       Image image = ImageIO.read(is);
+                       EVENT_IMAGES.put(type, image);
+               } catch (IOException ignore) {
+                       ignore.printStackTrace();
+               }
+       }
+       
+       
+
 
-    private static void loadImage(FlightEvent.Type type, String file) {
-       InputStream is;
-       is = ClassLoader.getSystemResourceAsStream(file);
-       if (is == null) {
-               System.out.println("ERROR: File " + file + " not found!");
-               return;
-       }
-       
-       try {
-               Image image = ImageIO.read(is);
-               EVENT_IMAGES.put(type, image);
-       } catch (IOException ignore) {
-               ignore.printStackTrace();
-       }
-    }
-    
-    
-    
-    
-    private final List<ModifiedXYItemRenderer> renderers =
-       new ArrayList<ModifiedXYItemRenderer>();
+       private final List<ModifiedXYItemRenderer> renderers =
+                       new ArrayList<ModifiedXYItemRenderer>();
        
        private PlotDialog(Window parent, Simulation simulation, PlotConfiguration config) {
                super(parent, "Flight data plot");
@@ -125,33 +131,33 @@ public class PlotDialog extends JDialog {
                
                final boolean initialShowPoints = Prefs.getBoolean(Prefs.PLOT_SHOW_POINTS, false);
                
-               
+
                // Fill the auto-selections
                FlightDataBranch branch = simulation.getSimulatedData().getBranch(0);
                PlotConfiguration filled = config.fillAutoAxes(branch);
                List<Axis> axes = filled.getAllAxes();
-
+               
 
                // Create the data series for both axes
                XYSeriesCollection[] data = new XYSeriesCollection[2];
                data[0] = new XYSeriesCollection();
                data[1] = new XYSeriesCollection();
                
-               
+
                // Get the domain axis type
-               final FlightDataBranch.Type domainType = filled.getDomainAxisType();
+               final FlightDataType domainType = filled.getDomainAxisType();
                final Unit domainUnit = filled.getDomainAxisUnit();
                if (domainType == null) {
                        throw new IllegalArgumentException("Domain axis type not specified.");
                }
                List<Double> x = branch.get(domainType);
                
-               
+
                // Get plot length (ignore trailing NaN's)
                int typeCount = filled.getTypeCount();
                int dataLength = 0;
-               for (int i=0; i<typeCount; i++) {
-                       FlightDataBranch.Type type = filled.getType(i);
+               for (int i = 0; i < typeCount; i++) {
+                       FlightDataType type = filled.getType(i);
                        List<Double> y = branch.get(type);
                        
                        for (int j = dataLength; j < y.size(); j++) {
@@ -161,12 +167,12 @@ public class PlotDialog extends JDialog {
                }
                dataLength = Math.min(dataLength, x.size());
                
-               
+
                // Create the XYSeries objects from the flight data and store into the collections
                String[] axisLabel = new String[2];
                for (int i = 0; i < typeCount; i++) {
                        // Get info
-                       FlightDataBranch.Type type = filled.getType(i);
+                       FlightDataType type = filled.getType(i);
                        Unit unit = filled.getUnit(i);
                        int axis = filled.getAxis(i);
                        String name = getLabel(type, unit);
@@ -174,11 +180,11 @@ public class PlotDialog extends JDialog {
                        // Store data in provided units
                        List<Double> y = branch.get(type);
                        XYSeries series = new XYSeries(name, false, true);
-                       for (int j=0; j < dataLength; j++) {
+                       for (int j = 0; j < dataLength; j++) {
                                series.add(domainUnit.toUnit(x.get(j)), unit.toUnit(y.get(j)));
                        }
                        data[axis].addSeries(series);
-
+                       
                        // Update axis label
                        if (axisLabel[axis] == null)
                                axisLabel[axis] = type.getName();
@@ -186,25 +192,25 @@ public class PlotDialog extends JDialog {
                                axisLabel[axis] += "; " + type.getName();
                }
                
-               
+
                // Create the chart using the factory to get all default settings
-        JFreeChart chart = ChartFactory.createXYLineChart(
-            "Simulated flight",
-            null, 
-            null, 
-            null,
-            PlotOrientation.VERTICAL,
-            true,
-            true,
-            false
-        );
-               
-        chart.addSubtitle(new TextTitle(config.getName()));
-        
+               JFreeChart chart = ChartFactory.createXYLineChart(
+                               "Simulated flight",
+                               null,
+                               null,
+                               null,
+                               PlotOrientation.VERTICAL,
+                               true,
+                               true,
+                               false
+                               );
+               
+               chart.addSubtitle(new TextTitle(config.getName()));
+               
                // Add the data and formatting to the plot
                XYPlot plot = chart.getXYPlot();
                int axisno = 0;
-               for (int i=0; i<2; i++) {
+               for (int i = 0; i < 2; i++) {
                        // Check whether axis has any data
                        if (data[i].getSeriesCount() > 0) {
                                // Create and set axis
@@ -212,7 +218,7 @@ public class PlotDialog extends JDialog {
                                double max = axes.get(i).getMaxValue();
                                NumberAxis axis = new PresetNumberAxis(min, max);
                                axis.setLabel(axisLabel[i]);
-//                             axis.setRange(axes.get(i).getMinValue(), axes.get(i).getMaxValue());
+                               //                              axis.setRange(axes.get(i).getMinValue(), axes.get(i).getMaxValue());
                                plot.setRangeAxis(axisno, axis);
                                
                                // Add data and map to the axis
@@ -220,6 +226,9 @@ public class PlotDialog extends JDialog {
                                ModifiedXYItemRenderer r = new ModifiedXYItemRenderer();
                                r.setBaseShapesVisible(initialShowPoints);
                                r.setBaseShapesFilled(true);
+                               for (int j = 0; j < data[i].getSeriesCount(); j++) {
+                                       r.setSeriesStroke(j, new BasicStroke(PLOT_STROKE_WIDTH));
+                               }
                                renderers.add(r);
                                plot.setRenderer(axisno, r);
                                plot.mapDatasetToRangeAxis(axisno, axisno);
@@ -227,12 +236,12 @@ public class PlotDialog extends JDialog {
                        }
                }
                
-               plot.getDomainAxis().setLabel(getLabel(domainType,domainUnit));
+               plot.getDomainAxis().setLabel(getLabel(domainType, domainUnit));
                plot.addDomainMarker(new ValueMarker(0));
                plot.addRangeMarker(new ValueMarker(0));
                
-               
-               
+
+
                // Create list of events to show (combine event too close to each other)
                ArrayList<Double> timeList = new ArrayList<Double>();
                ArrayList<String> eventList = new ArrayList<String>();
@@ -246,17 +255,17 @@ public class PlotDialog extends JDialog {
                Color color = null;
                Image image = null;
                
-               List<Pair<Double, FlightEvent>> events = branch.getEvents();
-               for (int i=0; i < events.size(); i++) {
-                       Pair<Double, FlightEvent> event = events.get(i);
-                       double t = event.getU();
-                       FlightEvent.Type type = event.getV().getType();
+               List<FlightEvent> events = branch.getEvents();
+               for (int i = 0; i < events.size(); i++) {
+                       FlightEvent event = events.get(i);
+                       double t = event.getTime();
+                       FlightEvent.Type type = event.getType();
                        
                        if (type != FlightEvent.Type.ALTITUDE && config.isEventActive(type)) {
                                if (Math.abs(t - prevTime) <= 0.01) {
                                        
                                        if (!typeSet.contains(type)) {
-                                               text = text + ", " + event.getV().getType().toString();
+                                               text = text + ", " + type.toString();
                                                color = getEventColor(type);
                                                image = EVENT_IMAGES.get(type);
                                                typeSet.add(type);
@@ -287,13 +296,13 @@ public class PlotDialog extends JDialog {
                        imageList.add(image);
                }
                
-               
+
                // Create the event markers
                
-               if (config.getDomainAxisType() == FlightDataBranch.TYPE_TIME) {
+               if (config.getDomainAxisType() == FlightDataType.TYPE_TIME) {
                        
                        // Domain time is plotted as vertical markers
-                       for (int i=0; i < eventList.size(); i++) {
+                       for (int i = 0; i < eventList.size(); i++) {
                                double t = timeList.get(i);
                                String event = eventList.get(i);
                                color = colorList.get(i);
@@ -309,10 +318,10 @@ public class PlotDialog extends JDialog {
                } else {
                        
                        // Other domains are plotted as image annotations
-                       List<Double> time = branch.get(FlightDataBranch.TYPE_TIME);
+                       List<Double> time = branch.get(FlightDataType.TYPE_TIME);
                        List<Double> domain = branch.get(config.getDomainAxisType());
                        
-                       for (int i=0; i < eventList.size(); i++) {
+                       for (int i = 0; i < eventList.size(); i++) {
                                final double t = timeList.get(i);
                                String event = eventList.get(i);
                                image = imageList.get(i);
@@ -324,30 +333,29 @@ public class PlotDialog extends JDialog {
                                final double a;
                                int tindex = Collections.binarySearch(time, t);
                                if (tindex < 0) {
-                                       tindex = -tindex -1;
+                                       tindex = -tindex - 1;
                                }
                                if (tindex >= time.size()) {
                                        // index greater than largest value in time list
-                                       tindex = time.size()-1;
+                                       tindex = time.size() - 1;
                                        a = 0;
                                } else if (tindex <= 0) {
                                        // index smaller than smallest value in time list
                                        tindex = 0;
                                        a = 0;
                                } else {
-                                       assert(tindex > 0);
                                        tindex--;
                                        double t1 = time.get(tindex);
-                                       double t2 = time.get(tindex+1);
+                                       double t2 = time.get(tindex + 1);
                                        
                                        if ((t1 > t) || (t2 < t)) {
-                                               throw new RuntimeException("BUG: t1="+t1+" t2="+t2+" t="+t);
+                                               throw new BugException("t1=" + t1 + " t2=" + t2 + " t=" + t);
                                        }
                                        
                                        if (MathUtil.equals(t1, t2)) {
                                                a = 0;
                                        } else {
-                                               a = 1 - (t-t1) / (t2-t1);
+                                               a = 1 - (t - t1) / (t2 - t1);
                                        }
                                }
                                
@@ -355,29 +363,29 @@ public class PlotDialog extends JDialog {
                                if (a == 0) {
                                        xcoord = domain.get(tindex);
                                } else {
-                                       xcoord = a * domain.get(tindex) + (1-a) * domain.get(tindex+1);
+                                       xcoord = a * domain.get(tindex) + (1 - a) * domain.get(tindex + 1);
                                }
                                
                                for (int index = 0; index < config.getTypeCount(); index++) {
-                                       FlightDataBranch.Type type = config.getType(index);
+                                       FlightDataType type = config.getType(index);
                                        List<Double> range = branch.get(type);
                                        
                                        final double ycoord;
                                        if (a == 0) {
                                                ycoord = range.get(tindex);
                                        } else {
-                                               ycoord = a * range.get(tindex) + (1-a) * range.get(tindex+1);
+                                               ycoord = a * range.get(tindex) + (1 - a) * range.get(tindex + 1);
                                        }
                                        
-                                       XYImageAnnotation annotation = 
-                                               new XYImageAnnotation(xcoord, ycoord, image, RectangleAnchor.CENTER);
+                                       XYImageAnnotation annotation =
+                                                       new XYImageAnnotation(xcoord, ycoord, image, RectangleAnchor.CENTER);
                                        annotation.setToolTipText(event);
                                        plot.addAnnotation(annotation);
                                }
                        }
                }
                
-               
+
                // Create the dialog
                
                JPanel panel = new JPanel(new MigLayout("fill"));
@@ -385,9 +393,9 @@ public class PlotDialog extends JDialog {
                
                ChartPanel chartPanel = new ChartPanel(chart,
                                false, // properties
-                               true,  // save
+                               true, // save
                                false, // print
-                               true,  // zoom
+                               true, // zoom
                                true); // tooltips
                chartPanel.setMouseWheelEnabled(true);
                chartPanel.setEnforceFileExtensions(true);
@@ -397,22 +405,27 @@ public class PlotDialog extends JDialog {
                
                panel.add(chartPanel, "grow, wrap 20lp");
                
-               final JCheckBox check = new JCheckBox("Show points");
+               final JCheckBox check = new JCheckBox("Show data points");
                check.setSelected(initialShowPoints);
                check.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                                boolean show = check.isSelected();
                                Prefs.putBoolean(Prefs.PLOT_SHOW_POINTS, show);
-                               for (ModifiedXYItemRenderer r: renderers) {
+                               for (ModifiedXYItemRenderer r : renderers) {
                                        r.setBaseShapesVisible(show);
                                }
                        }
                });
                panel.add(check, "split, left");
                
-               panel.add(new JPanel(), "growx");
 
+               JLabel label = new StyledLabel("Click+drag down+right to zoom in, up+left to zoom out", -2);
+               panel.add(label, "gapleft para");
+               
+
+               panel.add(new JPanel(), "growx");
+               
                JButton button = new JButton("Close");
                button.addActionListener(new ActionListener() {
                        @Override
@@ -421,24 +434,24 @@ public class PlotDialog extends JDialog {
                        }
                });
                panel.add(button, "right");
-
+               
                this.setLocationByPlatform(true);
                this.pack();
-               GUIUtil.installEscapeCloseOperation(this);
-               GUIUtil.setDefaultButton(button);
+               
+               GUIUtil.setDisposableDialogOptions(this, button);
        }
        
        
-       private String getLabel(FlightDataBranch.Type type, Unit unit) {
+       private String getLabel(FlightDataType type, Unit unit) {
                String name = type.getName();
-               if (unit != null  &&  !UnitGroup.UNITS_NONE.contains(unit)  &&
+               if (unit != null && !UnitGroup.UNITS_NONE.contains(unit) &&
                                !UnitGroup.UNITS_COEFFICIENT.contains(unit) && unit.getUnit().length() > 0)
-                       name += " ("+unit.getUnit() + ")";
+                       name += " (" + unit.getUnit() + ")";
                return name;
        }
        
-
        
+
        private class PresetNumberAxis extends NumberAxis {
                private final double min;
                private final double max;
@@ -468,7 +481,7 @@ public class PlotDialog extends JDialog {
        }
        
        
-       
+
        private static Color getEventColor(FlightEvent.Type type) {
                Color c = EVENT_COLORS.get(type);
                if (c != null)
@@ -478,24 +491,24 @@ public class PlotDialog extends JDialog {
        
        
 
-       
-       
+
+
        /**
         * A modification to the standard renderer that renders the domain marker
         * labels vertically instead of horizontally.
         */
        private static class ModifiedXYItemRenderer extends StandardXYItemRenderer {
-
+               
                @Override
                public void drawDomainMarker(Graphics2D g2, XYPlot plot, ValueAxis domainAxis,
                                Marker marker, Rectangle2D dataArea) {
-
+                       
                        if (!(marker instanceof ValueMarker)) {
                                // Use parent for all others
                                super.drawDomainMarker(g2, plot, domainAxis, marker, dataArea);
                                return;
                        }
-
+                       
                        /*
                         * Draw the normal marker, but with rotated text.
                         * Copied from the overridden method.
@@ -506,9 +519,9 @@ public class PlotDialog extends JDialog {
                        if (!range.contains(value)) {
                                return;
                        }
-
+                       
                        double v = domainAxis.valueToJava2D(value, dataArea, plot.getDomainAxisEdge());
-
+                       
                        PlotOrientation orientation = plot.getOrientation();
                        Line2D line = null;
                        if (orientation == PlotOrientation.HORIZONTAL) {
@@ -516,14 +529,14 @@ public class PlotDialog extends JDialog {
                        } else {
                                line = new Line2D.Double(v, dataArea.getMinY(), v, dataArea.getMaxY());
                        }
-
+                       
                        final Composite originalComposite = g2.getComposite();
                        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, marker
                                        .getAlpha()));
                        g2.setPaint(marker.getPaint());
                        g2.setStroke(marker.getStroke());
                        g2.draw(line);
-
+                       
                        String label = marker.getLabel();
                        RectangleAnchor anchor = marker.getLabelAnchor();
                        if (label != null) {
@@ -536,13 +549,13 @@ public class PlotDialog extends JDialog {
                                
                                // Changed:
                                TextAnchor textAnchor = TextAnchor.TOP_RIGHT;
-                               TextUtilities.drawRotatedString(label, g2, (float) coordinates.getX()+2,
+                               TextUtilities.drawRotatedString(label, g2, (float) coordinates.getX() + 2,
                                                (float) coordinates.getY(), textAnchor,
-                                               -Math.PI/2, textAnchor);
+                                               -Math.PI / 2, textAnchor);
                        }
                        g2.setComposite(originalComposite);
                }
-
+               
        }
-
+       
 }