diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index fa2be3098..bd2da08b5 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -820,6 +820,12 @@ simplotpanel.MarkerStyle.btn.VerticalMarker = Vertical line simplotpanel.MarkerStyle.btn.Icon = Icon simplotpanel.MarkerStyle.OnlyInTime = Only available for time domain, other domains only support icon markers +! Simulation plot +simulationplot.abort.title = Simulation Abort +simulationplot.abort.stage = Stage +simulationplot.abort.time = Time +simulationplot.abort.cause = Cause + ! FlightDataComboBox FlightDataComboBox.placeholder = Enter the data type diff --git a/core/src/net/sf/openrocket/simulation/FlightDataBranch.java b/core/src/net/sf/openrocket/simulation/FlightDataBranch.java index 395c96343..4ccdf9041 100644 --- a/core/src/net/sf/openrocket/simulation/FlightDataBranch.java +++ b/core/src/net/sf/openrocket/simulation/FlightDataBranch.java @@ -46,7 +46,7 @@ public class FlightDataBranch implements Monitorable { * Altitude the rocket would reach if there had been no recovery deployment. */ private double optimumAltitude = Double.NaN; - + private final ArrayList events = new ArrayList(); private final Mutable mutable = new Mutable(); diff --git a/core/src/net/sf/openrocket/simulation/SimulationStatus.java b/core/src/net/sf/openrocket/simulation/SimulationStatus.java index 92d221539..bb5a64a91 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationStatus.java +++ b/core/src/net/sf/openrocket/simulation/SimulationStatus.java @@ -93,10 +93,6 @@ public class SimulationStatus implements Monitorable { private int modID = 0; private int modIDadd = 0; - - // if the simulation is aborted, store the abort event here for later display - // in the sim plot window - private FlightEvent abortEvent = null; public SimulationStatus(FlightConfiguration configuration, SimulationConditions simulationConditions) { @@ -572,8 +568,8 @@ public class SimulationStatus implements Monitorable { * Abort the current simulation branch */ public void abortSimulation(SimulationAbort cause) throws SimulationException { - abortEvent = new FlightEvent(FlightEvent.Type.SIM_ABORT, getSimulationTime(), null, cause); + FlightEvent abortEvent = new FlightEvent(FlightEvent.Type.SIM_ABORT, getSimulationTime(), null, cause); addEvent(abortEvent); } - + } diff --git a/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java b/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java index bb6d57e3c..4525bf5bb 100644 --- a/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java +++ b/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java @@ -21,6 +21,8 @@ import java.util.regex.Pattern; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.gui.simulation.SimulationPlotPanel; import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.logging.SimulationAbort; import net.sf.openrocket.simulation.FlightDataBranch; import net.sf.openrocket.simulation.FlightDataType; import net.sf.openrocket.simulation.FlightEvent; @@ -31,6 +33,7 @@ import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.util.LinearInterpolator; import net.sf.openrocket.utils.DecimalFormatter; +import org.jfree.chart.annotations.XYTitleAnnotation; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.LegendItem; @@ -50,6 +53,8 @@ import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.title.LegendTitle; import org.jfree.chart.title.TextTitle; +import org.jfree.ui.HorizontalAlignment; +import org.jfree.ui.VerticalAlignment; import org.jfree.data.Range; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; @@ -68,9 +73,10 @@ import org.jfree.ui.TextAnchor; */ @SuppressWarnings("serial") public class SimulationPlot { + private static final Translator trans = Application.getTranslator(); + private static final SwingPreferences preferences = (SwingPreferences) Application.getPreferences(); - private static final float PLOT_STROKE_WIDTH = 1.5f; private final JFreeChart chart; @@ -104,6 +110,7 @@ public class SimulationPlot { } } drawDomainMarkers(branch); + drawAborts(branch); } SimulationPlot(Simulation simulation, PlotConfiguration config, boolean initialShowPoints) { @@ -335,6 +342,8 @@ public class SimulationPlot { // Create the event markers drawDomainMarkers(-1); + // Display aborts (if any) + drawAborts(-1); } JFreeChart getJFreeChart() { @@ -583,6 +592,37 @@ public class SimulationPlot { } + /** + * Put all aborts in a text area + */ + private void drawAborts(int branchno) { + String abortString = ""; + + for (int b = Math.max(0, branchno); + b < ((branchno < 0) ? + (simulation.getSimulatedData().getBranchCount()) : + (branchno + 1)); b++) { + FlightDataBranch branch = simulation.getSimulatedData().getBranch(b); + final List events = branch.getEvents(); + for (FlightEvent event: events) { + if (event.getType() == FlightEvent.Type.SIM_ABORT) { + if (abortString == "") { + abortString = trans.get("simulationplot.abort.title"); + } + abortString += "\n" + trans.get("simulationplot.abort.stage") + ": " + branch.getBranchName() + + ", " + trans.get("simulationplot.abort.time") + ": " + event.getTime() + + ", " + trans.get("simulationplot.abort.cause") + ": " + ((SimulationAbort)event.getData()).getMessageDescription(); + } + } + } + + TextTitle abortsTitle = new TextTitle(abortString, new Font(Font.SANS_SERIF, Font.BOLD, 14), Color.RED, RectangleEdge.TOP, HorizontalAlignment.LEFT, + VerticalAlignment.TOP, RectangleInsets.ZERO_INSETS); + XYTitleAnnotation abortsAnnotation = new XYTitleAnnotation(0.9, 1, abortsTitle, RectangleAnchor.TOP_RIGHT); + + chart.getXYPlot().addAnnotation(abortsAnnotation); + } + private static class LegendItems implements LegendItemSource { private final List lineLabels = new ArrayList();