From 48526af8b8e9969e31524158fc86ef17420aebd0 Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Tue, 9 Jan 2024 14:31:05 -0700 Subject: [PATCH] create "Show errors" checkbox, making it possible to hide/show simulation aborts. I'm following the lead of the design window "Show warnings" checkbox here, and leaving the checkbox present even if there are no errors. --- core/resources/l10n/messages.properties | 2 + .../openrocket/gui/plot/SimulationPlot.java | 153 +++++++++++++----- .../gui/plot/SimulationPlotDialog.java | 22 ++- 3 files changed, 130 insertions(+), 47 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 641c48fb4..6f96ed80d 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -1606,6 +1606,8 @@ TCMotorSelPan.btn.close = Close ! PlotDialog PlotDialog.CheckBox.Showdatapoints = Show data points +PlotDialog.CheckBox.ShowErrors = Show errors + PlotDialog.lbl.Chart = left click drag to zoom area. mouse wheel to zoom. ctrl-mouse wheel to zoom x axis only. ctrl-left click drag to pan. right click drag to zoom dynamically. PlotDialog.lbl.timeSeriesWarning = The data is plotted in time order even though the X axis type is not time. PlotDialog.btn.exportImage = Export Image diff --git a/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java b/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java index 540a43ee1..eba41df68 100644 --- a/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java +++ b/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java @@ -90,6 +90,8 @@ public class SimulationPlot { private final LegendItems legendItems; + private ErrorAnnotationSet errorAnnotations = null; + private int branchCount; void setShowPoints(boolean showPoints) { @@ -98,6 +100,10 @@ public class SimulationPlot { } } + void setShowErrors(boolean showErrors) { + errorAnnotations.setVisible(showErrors); + } + void setShowBranch(int branch) { XYPlot plot = (XYPlot) chart.getPlot(); int datasetcount = plot.getDatasetCount(); @@ -109,8 +115,10 @@ public class SimulationPlot { r.setSeriesVisible(j, show); } } + drawDomainMarkers(branch); - drawAborts(branch); + + errorAnnotations.setCurrent(branch); } SimulationPlot(Simulation simulation, PlotConfiguration config, boolean initialShowPoints) { @@ -342,8 +350,7 @@ public class SimulationPlot { // Create the event markers drawDomainMarkers(-1); - // Display aborts (if any) - drawAborts(-1); + errorAnnotations = new ErrorAnnotationSet(branchCount); } JFreeChart getJFreeChart() { @@ -595,45 +602,6 @@ public class SimulationPlot { return eventList; } - - /** - * 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(); - } - } - } - - if (abortString != "") { - TextTitle abortsTitle = new TextTitle(abortString, - new Font(Font.SANS_SERIF, Font.BOLD, 14), Color.RED, - RectangleEdge.TOP, - HorizontalAlignment.LEFT, VerticalAlignment.TOP, - new RectangleInsets(5, 5, 5, 5)); - abortsTitle.setBackgroundPaint(Color.WHITE); - BlockBorder abortsBorder = new BlockBorder(Color.RED); - abortsTitle.setFrame(abortsBorder); - XYTitleAnnotation abortsAnnotation = new XYTitleAnnotation(0.01, 0.01, abortsTitle, RectangleAnchor.BOTTOM_LEFT); - - chart.getXYPlot().addAnnotation(abortsAnnotation); - } - } private static class LegendItems implements LegendItemSource { @@ -839,5 +807,106 @@ public class SimulationPlot { FlightEvent event; } + /** + * Is there really no way to set an annotation invisible? This class kludges provides a way + * to select at most one from a set of annotations and make it visible. + */ + private class ErrorAnnotationSet { + private XYTitleAnnotation[] errorAnnotations; + private XYTitleAnnotation currentAnnotation; + private boolean visible = true; + private int branchCount; + + protected ErrorAnnotationSet(int branches) { + branchCount = branches; + errorAnnotations = new XYTitleAnnotation[branchCount+1]; + + for (int b = -1; b < branchCount; b++) { + if (b < 0) { + errorAnnotations[branchCount] = createAnnotation(b); + } else { + errorAnnotations[b] = createAnnotation(b); + } + } + setCurrent(-1); + } + + private XYTitleAnnotation createAnnotation(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); + FlightEvent abortEvent = branch.getFirstEvent(FlightEvent.Type.SIM_ABORT); + if (abortEvent != null) { + if (abortString == "") { + abortString = trans.get("simulationplot.abort.title"); + } + abortString += "\n" + trans.get("simulationplot.abort.stage") + ": " + branch.getBranchName() + + ", " + trans.get("simulationplot.abort.time") + ": " + abortEvent.getTime() + + ", " + trans.get("simulationplot.abort.cause") + ": " + ((SimulationAbort)abortEvent.getData()).getMessageDescription(); + } + } + + if (abortString != "") { + TextTitle abortsTitle = new TextTitle(abortString, + new Font(Font.SANS_SERIF, Font.BOLD, 14), Color.RED, + RectangleEdge.TOP, + HorizontalAlignment.LEFT, VerticalAlignment.TOP, + new RectangleInsets(5, 5, 5, 5)); + abortsTitle.setBackgroundPaint(Color.WHITE); + BlockBorder abortsBorder = new BlockBorder(Color.RED); + abortsTitle.setFrame(abortsBorder); + + return new XYTitleAnnotation(0.01, 0.01, abortsTitle, RectangleAnchor.BOTTOM_LEFT); + } else { + return null; + } + } + + protected void setCurrent(int branchNo) { + XYPlot plot = chart.getXYPlot(); + // If we are currently displaying an annotation, and we want to + // change to a new branch, stop displaying the old annotation + + XYTitleAnnotation newAnnotation = (branchNo < 0) ? + errorAnnotations[branchCount] : + errorAnnotations[branchNo]; + + // if we're currently displaying an annotation, and it's different + // from the new annotation, stop displaying it + if ((currentAnnotation != null) && + (currentAnnotation != newAnnotation) && + visible) { + plot.removeAnnotation(currentAnnotation); + } + + // set our current annotation + currentAnnotation = newAnnotation; + + // if visible, display it + if ((currentAnnotation != null) && visible) { + plot.addAnnotation(currentAnnotation); + } + } + + protected void setVisible(boolean v) { + if (visible != v) { + visible = v; + if (currentAnnotation != null) { + XYPlot plot = chart.getXYPlot(); + + if (visible) { + plot.addAnnotation(currentAnnotation); + } else { + plot.removeAnnotation(currentAnnotation); + } + } + } + } + } } diff --git a/swing/src/net/sf/openrocket/gui/plot/SimulationPlotDialog.java b/swing/src/net/sf/openrocket/gui/plot/SimulationPlotDialog.java index 793da42b7..52ca5f144 100644 --- a/swing/src/net/sf/openrocket/gui/plot/SimulationPlotDialog.java +++ b/swing/src/net/sf/openrocket/gui/plot/SimulationPlotDialog.java @@ -86,17 +86,29 @@ public class SimulationPlotDialog extends JDialog { } //// Show data points - final JCheckBox check = new JCheckBox(trans.get("PlotDialog.CheckBox.Showdatapoints")); - check.setSelected(initialShowPoints); - check.addActionListener(new ActionListener() { + final JCheckBox checkData = new JCheckBox(trans.get("PlotDialog.CheckBox.Showdatapoints")); + checkData.setSelected(initialShowPoints); + checkData.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - boolean show = check.isSelected(); + boolean show = checkData.isSelected(); Application.getPreferences().putBoolean(Preferences.PLOT_SHOW_POINTS, show); myPlot.setShowPoints(show); } }); - panel.add(check, "split, left"); + panel.add(checkData, "split, left"); + + //// Show errors + //// ALWAYS show errors initially; make user turn it off for themselves + final JCheckBox checkErrors = new JCheckBox(trans.get("PlotDialog.CheckBox.ShowErrors")); + checkErrors.setSelected(true); + checkErrors.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + myPlot.setShowErrors(checkErrors.isSelected()); + } + }); + panel.add(checkErrors, "split, left"); //// Add series selection box ArrayList stages = new ArrayList();