[#2525] Allow component analysis to be exported to a CSV file
This commit is contained in:
parent
1840bd4c0e
commit
525190b37f
@ -7,15 +7,23 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import info.openrocket.core.componentanalysis.CADataBranch;
|
||||||
|
import info.openrocket.core.componentanalysis.CADataType;
|
||||||
|
import info.openrocket.core.componentanalysis.CADomainDataType;
|
||||||
|
import info.openrocket.core.componentanalysis.CAParameters;
|
||||||
import info.openrocket.core.logging.Warning;
|
import info.openrocket.core.logging.Warning;
|
||||||
import info.openrocket.core.logging.WarningSet;
|
import info.openrocket.core.logging.WarningSet;
|
||||||
import info.openrocket.core.document.Simulation;
|
import info.openrocket.core.document.Simulation;
|
||||||
|
import info.openrocket.core.rocketcomponent.AxialStage;
|
||||||
|
import info.openrocket.core.rocketcomponent.RocketComponent;
|
||||||
import info.openrocket.core.simulation.FlightData;
|
import info.openrocket.core.simulation.FlightData;
|
||||||
import info.openrocket.core.simulation.FlightDataBranch;
|
import info.openrocket.core.simulation.FlightDataBranch;
|
||||||
import info.openrocket.core.simulation.FlightDataType;
|
import info.openrocket.core.simulation.FlightDataType;
|
||||||
import info.openrocket.core.simulation.FlightEvent;
|
import info.openrocket.core.simulation.FlightEvent;
|
||||||
import info.openrocket.core.unit.Unit;
|
import info.openrocket.core.unit.Unit;
|
||||||
|
import info.openrocket.core.util.StringUtils;
|
||||||
import info.openrocket.core.util.TextUtil;
|
import info.openrocket.core.util.TextUtil;
|
||||||
|
|
||||||
public class CSVExport {
|
public class CSVExport {
|
||||||
@ -51,7 +59,6 @@ public class CSVExport {
|
|||||||
|
|
||||||
PrintWriter writer = null;
|
PrintWriter writer = null;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
writer = new PrintWriter(stream, false, StandardCharsets.UTF_8);
|
writer = new PrintWriter(stream, false, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
// Write the initial comments
|
// Write the initial comments
|
||||||
@ -88,10 +95,66 @@ public class CSVExport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeData(PrintWriter writer, FlightDataBranch branch,
|
public static void exportCSV(OutputStream stream, CAParameters parameters, CADataBranch branch,
|
||||||
FlightDataType[] fields, Unit[] units, String fieldSeparator, int decimalPlaces,
|
CADomainDataType domainDataType, CADataType[] fields,
|
||||||
boolean isExponentialNotation,
|
Map<CADataType, List<RocketComponent>> components, Unit[] units,
|
||||||
boolean eventComments, String commentStarter) {
|
String fieldSeparator, int decimalPlaces, boolean isExponentialNotation,
|
||||||
|
boolean analysisComments, boolean fieldDescriptions, String commentStarter) throws IOException {
|
||||||
|
if (fields.length != units.length) {
|
||||||
|
throw new IllegalArgumentException("fields and units lengths must be equal " +
|
||||||
|
"(" + fields.length + " vs " + units.length + ")");
|
||||||
|
}
|
||||||
|
if (fields.length != components.size()) {
|
||||||
|
throw new IllegalArgumentException("fields and components lengths must be equal " +
|
||||||
|
"(" + fields.length + " vs " + components.size() + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintWriter writer = null;
|
||||||
|
try {
|
||||||
|
writer = new PrintWriter(stream, false, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
// Component analysis comments
|
||||||
|
if (analysisComments) {
|
||||||
|
writeComponentAnalysisComments(writer, parameters, branch, domainDataType, fields, components,
|
||||||
|
fieldSeparator, commentStarter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field names
|
||||||
|
if (fieldDescriptions) {
|
||||||
|
writer.print(prependComment(commentStarter, StringUtils.removeHTMLTags(domainDataType.getName())));
|
||||||
|
writer.print(fieldSeparator);
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
for (int j = 0; j < components.get(fields[i]).size(); j++) {
|
||||||
|
writer.print(StringUtils.removeHTMLTags(fields[i].getName()) +
|
||||||
|
" (" + components.get(fields[i]).get(j).getName() + ") (" +
|
||||||
|
units[i].getUnit() + ")");
|
||||||
|
if (i < fields.length - 1) {
|
||||||
|
writer.print(fieldSeparator);
|
||||||
|
} else if (j < components.get(fields[i]).size() - 1) {
|
||||||
|
writer.print(fieldSeparator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
writeData(writer, branch, domainDataType, fields, components, units, fieldSeparator, decimalPlaces,
|
||||||
|
isExponentialNotation);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (writer != null) {
|
||||||
|
try {
|
||||||
|
writer.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeData(PrintWriter writer, FlightDataBranch branch, FlightDataType[] fields, Unit[] units,
|
||||||
|
String fieldSeparator, int decimalPlaces, boolean isExponentialNotation,
|
||||||
|
boolean eventComments, String commentStarter) {
|
||||||
// Time variable
|
// Time variable
|
||||||
List<Double> time = branch.get(FlightDataType.TYPE_TIME);
|
List<Double> time = branch.get(FlightDataType.TYPE_TIME);
|
||||||
|
|
||||||
@ -120,7 +183,6 @@ public class CSVExport {
|
|||||||
|
|
||||||
// Loop over all data points
|
// Loop over all data points
|
||||||
for (int pos = 0; pos < n; pos++) {
|
for (int pos = 0; pos < n; pos++) {
|
||||||
|
|
||||||
// Check for events to store
|
// Check for events to store
|
||||||
if (eventComments && time != null) {
|
if (eventComments && time != null) {
|
||||||
double t = time.get(pos);
|
double t = time.get(pos);
|
||||||
@ -142,7 +204,6 @@ public class CSVExport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.println();
|
writer.println();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store any remaining events
|
// Store any remaining events
|
||||||
@ -152,13 +213,54 @@ public class CSVExport {
|
|||||||
eventPosition++;
|
eventPosition++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeData(PrintWriter writer, CADataBranch branch, CADomainDataType domainDataType,
|
||||||
|
CADataType[] fields, Map<CADataType, List<RocketComponent>> components, Unit[] units,
|
||||||
|
String fieldSeparator, int decimalPlaces, boolean isExponentialNotation) {
|
||||||
|
List<Double> domainValues = branch.get(domainDataType);
|
||||||
|
|
||||||
|
int n = domainValues != null ? domainValues.size() : branch.getLength();
|
||||||
|
|
||||||
|
// List of field values
|
||||||
|
List<List<Double>> fieldValues = new ArrayList<>();
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
Unit unit = units[i];
|
||||||
|
for (RocketComponent c : components.get(fields[i])) {
|
||||||
|
List<Double> values = branch.get(fields[i], c);
|
||||||
|
|
||||||
|
// Convert the values to the correct unit
|
||||||
|
values.replaceAll(unit::toUnit);
|
||||||
|
|
||||||
|
fieldValues.add(values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop over all data points
|
||||||
|
for (int pos = 0; pos < n; pos++) {
|
||||||
|
// Store domain type
|
||||||
|
if (domainValues != null) {
|
||||||
|
writer.print(TextUtil.doubleToString(domainValues.get(pos), decimalPlaces, isExponentialNotation));
|
||||||
|
writer.print(fieldSeparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store CSV line
|
||||||
|
for (int i = 0; i < fieldValues.size(); i++) {
|
||||||
|
double value = fieldValues.get(i).get(pos);
|
||||||
|
writer.print(TextUtil.doubleToString(value, decimalPlaces, isExponentialNotation));
|
||||||
|
|
||||||
|
if (i < fieldValues.size() - 1) {
|
||||||
|
writer.print(fieldSeparator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.println();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void printEvent(PrintWriter writer, FlightEvent e,
|
private static void printEvent(PrintWriter writer, FlightEvent e,
|
||||||
String commentStarter) {
|
String commentStarter) {
|
||||||
writer.println(commentStarter + " Event " + e.getType().name() +
|
writer.println(prependComment(commentStarter, "Event " + e.getType().name() +
|
||||||
" occurred at t=" + TextUtil.doubleToString(e.getTime()) + " seconds");
|
" occurred at t=" + TextUtil.doubleToString(e.getTime()) + " seconds"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeSimulationComments(PrintWriter writer,
|
private static void writeSimulationComments(PrintWriter writer,
|
||||||
@ -193,23 +295,70 @@ public class CSVExport {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.println(commentStarter + " " + line);
|
writer.println(prependComment(commentStarter,line));
|
||||||
|
|
||||||
writer.println(commentStarter + " " + branch.getLength() + " data points written for "
|
writer.println(prependComment(commentStarter, branch.getLength() + " data points written for "
|
||||||
+ fields.length + " variables.");
|
+ fields.length + " variables."));
|
||||||
|
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
writer.println(commentStarter + " No simulation data available.");
|
writer.println(prependComment(commentStarter, "No simulation data available."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WarningSet warnings = data.getWarningSet();
|
WarningSet warnings = data.getWarningSet();
|
||||||
|
|
||||||
if (!warnings.isEmpty()) {
|
if (!warnings.isEmpty()) {
|
||||||
writer.println(commentStarter + " Simulation warnings:");
|
writer.println(prependComment(commentStarter,"Simulation warnings:"));
|
||||||
for (Warning w : warnings) {
|
for (Warning w : warnings) {
|
||||||
writer.println(commentStarter + " " + w.toString());
|
writer.println(prependComment(commentStarter, " " + w.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void writeComponentAnalysisComments(PrintWriter writer, CAParameters parameters, CADataBranch branch,
|
||||||
|
CADomainDataType domainDataType, CADataType[] fields,
|
||||||
|
Map<CADataType, List<RocketComponent>> components,
|
||||||
|
String fieldSeparator, String commentStarter) {
|
||||||
|
StringBuilder line = new StringBuilder(prependComment(commentStarter, "Parameters:")).append(fieldSeparator);
|
||||||
|
|
||||||
|
// TODO: use proper units for the parameters
|
||||||
|
if (domainDataType != CADomainDataType.WIND_DIRECTION) {
|
||||||
|
line.append("Wind direction:").append(fieldSeparator);
|
||||||
|
line.append(parameters.getTheta()).append("°").append(fieldSeparator);
|
||||||
|
}
|
||||||
|
if (domainDataType != CADomainDataType.AOA) {
|
||||||
|
line.append("Angle of attack:").append(fieldSeparator);
|
||||||
|
line.append(parameters.getAOA()).append("°").append(fieldSeparator);
|
||||||
|
}
|
||||||
|
if (domainDataType != CADomainDataType.MACH) {
|
||||||
|
line.append("Mach:").append(fieldSeparator);
|
||||||
|
line.append(parameters.getMach()).append(fieldSeparator);
|
||||||
|
}
|
||||||
|
if (domainDataType != CADomainDataType.ROLL_RATE) {
|
||||||
|
line.append("Roll rate:").append(fieldSeparator);
|
||||||
|
line.append(parameters.getRollRate()).append("°/s").append(fieldSeparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
line.append("Active stages:").append(fieldSeparator);
|
||||||
|
List<AxialStage> activeStages = parameters.getSelectedConfiguration().getActiveStages();
|
||||||
|
for (AxialStage stage: activeStages) {
|
||||||
|
line.append(stage.getName()).append(fieldSeparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
line.append("Flight configuration:").append(fieldSeparator);
|
||||||
|
line.append(parameters.getSelectedConfiguration().getName());
|
||||||
|
|
||||||
|
writer.println(line);
|
||||||
|
|
||||||
|
int nrOfVariables = 0;
|
||||||
|
for (CADataType t : fields) {
|
||||||
|
nrOfVariables += components.get(t).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.println(prependComment(commentStarter, branch.getLength() + " data points written for "
|
||||||
|
+ nrOfVariables + " variables."));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String prependComment(String commentStarter, String comment) {
|
||||||
|
return commentStarter + " " + comment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,4 +104,7 @@ public class StringUtils {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String removeHTMLTags(String input) {
|
||||||
|
return input.replaceAll("<[^>]*>", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -968,6 +968,8 @@ CAPlotExportDialog.tab.Export = Export
|
|||||||
|
|
||||||
! CAExportPanel
|
! CAExportPanel
|
||||||
CAExportPanel.Col.Components = Components
|
CAExportPanel.Col.Components = Components
|
||||||
|
CAExportPanel.checkbox.Includecadesc = Include component analysis description
|
||||||
|
CAExportPanel.checkbox.ttip.Includecadesc = Include information at the beginning of the file describing the component analysis.
|
||||||
|
|
||||||
! CADataTypeGroup
|
! CADataTypeGroup
|
||||||
CADataTypeGroup.DOMAIN = Domain Parameter
|
CADataTypeGroup.DOMAIN = Domain Parameter
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package info.openrocket.swing.gui.dialogs.componentanalysis;
|
package info.openrocket.swing.gui.dialogs.componentanalysis;
|
||||||
|
|
||||||
|
import info.openrocket.core.componentanalysis.CADataBranch;
|
||||||
import info.openrocket.core.componentanalysis.CADataType;
|
import info.openrocket.core.componentanalysis.CADataType;
|
||||||
import info.openrocket.core.l10n.Translator;
|
import info.openrocket.core.l10n.Translator;
|
||||||
import info.openrocket.core.rocketcomponent.RocketComponent;
|
import info.openrocket.core.rocketcomponent.RocketComponent;
|
||||||
@ -7,6 +8,7 @@ import info.openrocket.core.startup.Application;
|
|||||||
import info.openrocket.core.unit.Unit;
|
import info.openrocket.core.unit.Unit;
|
||||||
import info.openrocket.swing.gui.components.CsvOptionPanel;
|
import info.openrocket.swing.gui.components.CsvOptionPanel;
|
||||||
import info.openrocket.swing.gui.util.FileHelper;
|
import info.openrocket.swing.gui.util.FileHelper;
|
||||||
|
import info.openrocket.swing.gui.util.SaveCSVWorker;
|
||||||
import info.openrocket.swing.gui.util.SwingPreferences;
|
import info.openrocket.swing.gui.util.SwingPreferences;
|
||||||
import info.openrocket.swing.gui.widgets.CSVExportPanel;
|
import info.openrocket.swing.gui.widgets.CSVExportPanel;
|
||||||
import info.openrocket.swing.gui.widgets.SaveFileChooser;
|
import info.openrocket.swing.gui.widgets.SaveFileChooser;
|
||||||
@ -19,6 +21,7 @@ import javax.swing.JFileChooser;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import javax.swing.table.TableCellEditor;
|
import javax.swing.table.TableCellEditor;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
@ -41,15 +44,20 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
public class CAExportPanel extends CSVExportPanel<CADataType> {
|
public class CAExportPanel extends CSVExportPanel<CADataType> {
|
||||||
private static final long serialVersionUID = 4423905472892675964L;
|
private static final long serialVersionUID = 4423905472892675964L;
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
private static final int OPTION_FIELD_DESCRIPTIONS = 0;
|
|
||||||
private static final int FIXED_COMPONENT_COLUMN_WIDTH = 500;
|
private static final int FIXED_COMPONENT_COLUMN_WIDTH = 500;
|
||||||
|
|
||||||
|
private static final int OPTION_COMPONENT_ANALYSIS_COMMENTS = 0;
|
||||||
|
private static final int OPTION_FIELD_DESCRIPTIONS = 1;
|
||||||
|
|
||||||
private final List<Map<RocketComponent, Boolean>> selectedComponents;
|
private final List<Map<RocketComponent, Boolean>> selectedComponents;
|
||||||
|
private final ComponentAnalysisPlotExportPanel parent;
|
||||||
|
|
||||||
private CAExportPanel(ComponentAnalysisPlotExportPanel parent, CADataType[] types,
|
private CAExportPanel(ComponentAnalysisPlotExportPanel parent, CADataType[] types,
|
||||||
boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
|
boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
|
||||||
super(types, selected, csvOptions, true, extraComponents);
|
super(types, selected, csvOptions, true, extraComponents);
|
||||||
|
|
||||||
|
this.parent = parent;
|
||||||
|
|
||||||
selectedComponents = new ArrayList<>(types.length);
|
selectedComponents = new ArrayList<>(types.length);
|
||||||
Map<RocketComponent, Boolean> componentSelectedMap;
|
Map<RocketComponent, Boolean> componentSelectedMap;
|
||||||
List<RocketComponent> components;
|
List<RocketComponent> components;
|
||||||
@ -80,6 +88,8 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CsvOptionPanel csvOptions = new CsvOptionPanel(CAExportPanel.class, false,
|
CsvOptionPanel csvOptions = new CsvOptionPanel(CAExportPanel.class, false,
|
||||||
|
trans.get("CAExportPanel.checkbox.Includecadesc"),
|
||||||
|
trans.get("CAExportPanel.checkbox.ttip.Includecadesc"),
|
||||||
trans.get("SimExpPan.checkbox.Includefielddesc"),
|
trans.get("SimExpPan.checkbox.Includefielddesc"),
|
||||||
trans.get("SimExpPan.checkbox.ttip.Includefielddesc"));
|
trans.get("SimExpPan.checkbox.ttip.Includefielddesc"));
|
||||||
|
|
||||||
@ -94,9 +104,16 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
table.getColumnModel().getColumn(1).setCellRenderer(new LeftAlignedRenderer());
|
table.getColumnModel().getColumn(1).setCellRenderer(new LeftAlignedRenderer());
|
||||||
table.getColumnModel().getColumn(2).setCellRenderer(new LeftAlignedRenderer());
|
table.getColumnModel().getColumn(2).setCellRenderer(new LeftAlignedRenderer());
|
||||||
|
|
||||||
|
ComponentCheckBoxPanel.ComponentSelectionListener listener = (newStates) -> {
|
||||||
|
int row = table.getSelectedRow();
|
||||||
|
if (row != -1) {
|
||||||
|
selectedComponents.set(row, newStates);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
TableColumn componentColumn = table.getColumnModel().getColumn(3);
|
TableColumn componentColumn = table.getColumnModel().getColumn(3);
|
||||||
componentColumn.setCellRenderer(new ComponentCheckBoxRenderer());
|
componentColumn.setCellRenderer(new ComponentCheckBoxRenderer(listener));
|
||||||
componentColumn.setCellEditor(new ComponentCheckBoxEditor());
|
componentColumn.setCellEditor(new ComponentCheckBoxEditor(listener));
|
||||||
componentColumn.setPreferredWidth(FIXED_COMPONENT_COLUMN_WIDTH);
|
componentColumn.setPreferredWidth(FIXED_COMPONENT_COLUMN_WIDTH);
|
||||||
|
|
||||||
// Set specific client properties for FlatLaf
|
// Set specific client properties for FlatLaf
|
||||||
@ -105,6 +122,8 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doExport() {
|
public boolean doExport() {
|
||||||
|
CADataBranch branch = this.parent.runParameterSweep();
|
||||||
|
|
||||||
JFileChooser chooser = new SaveFileChooser();
|
JFileChooser chooser = new SaveFileChooser();
|
||||||
chooser.setFileFilter(FileHelper.CSV_FILTER);
|
chooser.setFileFilter(FileHelper.CSV_FILTER);
|
||||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||||
@ -126,7 +145,8 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
String fieldSep = csvOptions.getFieldSeparator();
|
String fieldSep = csvOptions.getFieldSeparator();
|
||||||
int decimalPlaces = csvOptions.getDecimalPlaces();
|
int decimalPlaces = csvOptions.getDecimalPlaces();
|
||||||
boolean isExponentialNotation = csvOptions.isExponentialNotation();
|
boolean isExponentialNotation = csvOptions.isExponentialNotation();
|
||||||
boolean fieldComment = csvOptions.getSelectionOption(OPTION_FIELD_DESCRIPTIONS);
|
boolean analysisComments = csvOptions.getSelectionOption(OPTION_COMPONENT_ANALYSIS_COMMENTS);
|
||||||
|
boolean fieldDescriptions = csvOptions.getSelectionOption(OPTION_FIELD_DESCRIPTIONS);
|
||||||
csvOptions.storePreferences();
|
csvOptions.storePreferences();
|
||||||
|
|
||||||
// Store preferences and export
|
// Store preferences and export
|
||||||
@ -150,6 +170,22 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<CADataType, List<RocketComponent>> components = new HashMap<>();
|
||||||
|
// Iterate through the table to get selected items
|
||||||
|
for (int i = 0; i < selected.length; i++) {
|
||||||
|
if (!selected[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Map.Entry<RocketComponent, Boolean> entry : selectedComponents.get(i).entrySet()) {
|
||||||
|
if (entry.getValue()) {
|
||||||
|
CADataType type = types[i];
|
||||||
|
List<RocketComponent> typeComponents = components.getOrDefault(type, new ArrayList<>());
|
||||||
|
typeComponents.add(entry.getKey());
|
||||||
|
components.put(type, typeComponents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fieldSep.equals(SPACE)) {
|
if (fieldSep.equals(SPACE)) {
|
||||||
fieldSep = " ";
|
fieldSep = " ";
|
||||||
} else if (fieldSep.equals(TAB)) {
|
} else if (fieldSep.equals(TAB)) {
|
||||||
@ -157,9 +193,9 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*SaveCSVWorker.export(file, simulation, branch, fieldTypes, fieldUnits, fieldSep, decimalPlaces,
|
SaveCSVWorker.exportCAData(file, parent.getParameters(), branch, parent.getSelectedParameter(), fieldTypes,
|
||||||
isExponentialNotation, commentChar, simulationComment, fieldComment, eventComment,
|
components, fieldUnits, fieldSep, decimalPlaces, isExponentialNotation, commentChar, analysisComments,
|
||||||
SwingUtilities.getWindowAncestor(this));*/
|
fieldDescriptions, SwingUtilities.getWindowAncestor(this));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -256,6 +292,11 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
|
|
||||||
private static class ComponentCheckBoxRenderer implements TableCellRenderer {
|
private static class ComponentCheckBoxRenderer implements TableCellRenderer {
|
||||||
private ComponentCheckBoxPanel panel;
|
private ComponentCheckBoxPanel panel;
|
||||||
|
private final ComponentCheckBoxPanel.ComponentSelectionListener listener;
|
||||||
|
|
||||||
|
public ComponentCheckBoxRenderer(ComponentCheckBoxPanel.ComponentSelectionListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||||
@ -270,6 +311,7 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
|
|
||||||
if (panel == null) {
|
if (panel == null) {
|
||||||
panel = new ComponentCheckBoxPanel(componentMap);
|
panel = new ComponentCheckBoxPanel(componentMap);
|
||||||
|
panel.setComponentSelectionListener(listener);
|
||||||
} else {
|
} else {
|
||||||
panel.updateComponentStates(componentMap);
|
panel.updateComponentStates(componentMap);
|
||||||
}
|
}
|
||||||
@ -284,7 +326,6 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
|
|
||||||
private static class ComponentCheckBoxPanel extends JPanel {
|
private static class ComponentCheckBoxPanel extends JPanel {
|
||||||
private final Map<RocketComponent, JCheckBox> checkBoxMap = new HashMap<>();
|
private final Map<RocketComponent, JCheckBox> checkBoxMap = new HashMap<>();
|
||||||
private final ItemListener checkBoxListener;
|
|
||||||
private final AtomicBoolean updatingState = new AtomicBoolean(false);
|
private final AtomicBoolean updatingState = new AtomicBoolean(false);
|
||||||
private Color gridColor = Color.GRAY;
|
private Color gridColor = Color.GRAY;
|
||||||
private boolean isSelected = false;
|
private boolean isSelected = false;
|
||||||
@ -297,20 +338,6 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
gbc.weightx = 1.0;
|
gbc.weightx = 1.0;
|
||||||
gbc.insets = new Insets(2, 2, 2, 2);
|
gbc.insets = new Insets(2, 2, 2, 2);
|
||||||
|
|
||||||
checkBoxListener = e -> {
|
|
||||||
if (updatingState.get()) return;
|
|
||||||
|
|
||||||
JCheckBox source = (JCheckBox) e.getSource();
|
|
||||||
if (e.getStateChange() == ItemEvent.DESELECTED) {
|
|
||||||
if (checkBoxMap.values().stream().noneMatch(JCheckBox::isSelected)) {
|
|
||||||
source.setSelected(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the table that the value has changed
|
|
||||||
firePropertyChange("value", null, getComponentStates());
|
|
||||||
};
|
|
||||||
|
|
||||||
createCheckBoxes(componentMap, gbc);
|
createCheckBoxes(componentMap, gbc);
|
||||||
|
|
||||||
// Add an empty component to push everything to the top-left
|
// Add an empty component to push everything to the top-left
|
||||||
@ -405,10 +432,44 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
g.fillRect(0, 0, getWidth(), getHeight() - 1);
|
g.fillRect(0, 0, getWidth(), getHeight() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ComponentSelectionListener {
|
||||||
|
void onComponentSelectionChanged(Map<RocketComponent, Boolean> newStates);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ComponentSelectionListener listener;
|
||||||
|
|
||||||
|
public void setComponentSelectionListener(ComponentSelectionListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ItemListener checkBoxListener = e -> {
|
||||||
|
if (updatingState.get()) return;
|
||||||
|
|
||||||
|
JCheckBox source = (JCheckBox) e.getSource();
|
||||||
|
if (e.getStateChange() == ItemEvent.DESELECTED) {
|
||||||
|
if (checkBoxMap.values().stream().noneMatch(JCheckBox::isSelected)) {
|
||||||
|
source.setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify the listener of the change
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onComponentSelectionChanged(getComponentStates());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify the table that the value has changed
|
||||||
|
firePropertyChange("value", null, getComponentStates());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ComponentCheckBoxEditor extends AbstractCellEditor implements TableCellEditor {
|
private static class ComponentCheckBoxEditor extends AbstractCellEditor implements TableCellEditor {
|
||||||
private ComponentCheckBoxPanel panel;
|
private ComponentCheckBoxPanel panel;
|
||||||
|
private final ComponentCheckBoxPanel.ComponentSelectionListener listener;
|
||||||
|
|
||||||
|
public ComponentCheckBoxEditor(ComponentCheckBoxPanel.ComponentSelectionListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
|
||||||
@ -424,6 +485,7 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
|||||||
|
|
||||||
if (panel == null) {
|
if (panel == null) {
|
||||||
panel = new ComponentCheckBoxPanel(componentMap);
|
panel = new ComponentCheckBoxPanel(componentMap);
|
||||||
|
panel.setComponentSelectionListener(listener);
|
||||||
} else {
|
} else {
|
||||||
panel.updateComponentStates(componentMap);
|
panel.updateComponentStates(componentMap);
|
||||||
}
|
}
|
||||||
|
@ -218,6 +218,10 @@ public class ComponentAnalysisPlotExportPanel extends JPanel {
|
|||||||
return (CADomainDataType) parameterSelector.getSelectedItem();
|
return (CADomainDataType) parameterSelector.getSelectedItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CAParameters getParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
private void updateModels(CADomainDataType type) {
|
private void updateModels(CADomainDataType type) {
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
throw new IllegalArgumentException("CADomainDataType cannot be null");
|
throw new IllegalArgumentException("CADomainDataType cannot be null");
|
||||||
|
@ -9,6 +9,7 @@ import info.openrocket.core.l10n.Translator;
|
|||||||
import info.openrocket.core.simulation.DataBranch;
|
import info.openrocket.core.simulation.DataBranch;
|
||||||
import info.openrocket.core.simulation.DataType;
|
import info.openrocket.core.simulation.DataType;
|
||||||
import info.openrocket.core.startup.Application;
|
import info.openrocket.core.startup.Application;
|
||||||
|
import info.openrocket.core.util.StringUtils;
|
||||||
|
|
||||||
public abstract class Util {
|
public abstract class Util {
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
@ -81,7 +82,7 @@ public abstract class Util {
|
|||||||
public static String formatHTMLString(String input) {
|
public static String formatHTMLString(String input) {
|
||||||
// TODO: Use AttributeString to format the string
|
// TODO: Use AttributeString to format the string
|
||||||
// Remove the HTML-like tags from the final string
|
// Remove the HTML-like tags from the final string
|
||||||
return input.replaceAll("<sub>|</sub>|<sup>|</sup>|<html>|</html>", "");
|
return StringUtils.removeHTMLTags(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Color getPlotColor(int index) {
|
public static Color getPlotColor(int index) {
|
||||||
|
@ -159,7 +159,7 @@ public class SimulationExportPanel extends CSVExportPanel<FlightDataType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SaveCSVWorker.export(file, simulation, branch, fieldTypes, fieldUnits, fieldSep, decimalPlaces,
|
SaveCSVWorker.exportSimulationData(file, simulation, branch, fieldTypes, fieldUnits, fieldSep, decimalPlaces,
|
||||||
isExponentialNotation, commentChar, simulationComment, fieldComment, eventComment,
|
isExponentialNotation, commentChar, simulationComment, fieldComment, eventComment,
|
||||||
SwingUtilities.getWindowAncestor(this));
|
SwingUtilities.getWindowAncestor(this));
|
||||||
|
|
||||||
|
@ -5,11 +5,18 @@ import java.io.BufferedOutputStream;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
|
|
||||||
|
import info.openrocket.core.componentanalysis.CADataBranch;
|
||||||
|
import info.openrocket.core.componentanalysis.CADataType;
|
||||||
|
import info.openrocket.core.componentanalysis.CADomainDataType;
|
||||||
|
import info.openrocket.core.componentanalysis.CAParameters;
|
||||||
|
import info.openrocket.core.rocketcomponent.RocketComponent;
|
||||||
import info.openrocket.swing.gui.dialogs.SwingWorkerDialog;
|
import info.openrocket.swing.gui.dialogs.SwingWorkerDialog;
|
||||||
|
|
||||||
import info.openrocket.core.document.Simulation;
|
import info.openrocket.core.document.Simulation;
|
||||||
@ -21,34 +28,47 @@ import info.openrocket.core.unit.Unit;
|
|||||||
import info.openrocket.core.util.BugException;
|
import info.openrocket.core.util.BugException;
|
||||||
import info.openrocket.core.util.TextUtil;
|
import info.openrocket.core.util.TextUtil;
|
||||||
|
|
||||||
|
|
||||||
public class SaveCSVWorker extends SwingWorker<Void, Void> {
|
public class SaveCSVWorker extends SwingWorker<Void, Void> {
|
||||||
|
|
||||||
private static final int BYTES_PER_FIELD_PER_POINT = 7;
|
private static final int BYTES_PER_FIELD_PER_POINT = 7;
|
||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
private final Simulation simulation;
|
|
||||||
private final FlightDataBranch branch;
|
|
||||||
private final FlightDataType[] fields;
|
|
||||||
private final Unit[] units;
|
|
||||||
private final String fieldSeparator;
|
private final String fieldSeparator;
|
||||||
private final int decimalPlaces;
|
private final int decimalPlaces;
|
||||||
private final boolean isExponentialNotation;
|
private final boolean isExponentialNotation;
|
||||||
private final String commentStarter;
|
private final String commentStarter;
|
||||||
private final boolean simulationComments;
|
|
||||||
private final boolean fieldComments;
|
// Simulation-specific fields
|
||||||
private final boolean eventComments;
|
private Simulation simulation;
|
||||||
|
private FlightDataBranch flightDataBranch;
|
||||||
|
private FlightDataType[] flightDataFields;
|
||||||
|
private Unit[] flightDataUnits;
|
||||||
|
private boolean simulationComments;
|
||||||
|
private boolean fieldComments;
|
||||||
|
private boolean eventComments;
|
||||||
|
|
||||||
|
// CA-specific fields
|
||||||
|
private CAParameters caParameters;
|
||||||
|
private CADataBranch caDataBranch;
|
||||||
|
private CADomainDataType caDomainDataType;
|
||||||
|
private CADataType[] caDataFields;
|
||||||
|
private Map<CADataType, List<RocketComponent>> caComponents;
|
||||||
|
private Unit[] caUnits;
|
||||||
|
private boolean analysisComments;
|
||||||
|
private boolean fieldDescriptions;
|
||||||
|
|
||||||
|
private boolean isCAData;
|
||||||
|
|
||||||
|
// Constructor for simulation data
|
||||||
public SaveCSVWorker(File file, Simulation simulation, FlightDataBranch branch,
|
public SaveCSVWorker(File file, Simulation simulation, FlightDataBranch branch,
|
||||||
FlightDataType[] fields, Unit[] units, String fieldSeparator, int decimalPlaces,
|
FlightDataType[] fields, Unit[] units, String fieldSeparator, int decimalPlaces,
|
||||||
boolean isExponentialNotation, String commentStarter, boolean simulationComments,
|
boolean isExponentialNotation, String commentStarter, boolean simulationComments,
|
||||||
boolean fieldComments, boolean eventComments) {
|
boolean fieldComments, boolean eventComments) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.simulation = simulation;
|
this.simulation = simulation;
|
||||||
this.branch = branch;
|
this.flightDataBranch = branch;
|
||||||
this.fields = fields;
|
this.flightDataFields = fields;
|
||||||
this.units = units;
|
this.flightDataUnits = units;
|
||||||
this.fieldSeparator = fieldSeparator;
|
this.fieldSeparator = fieldSeparator;
|
||||||
this.decimalPlaces = decimalPlaces;
|
this.decimalPlaces = decimalPlaces;
|
||||||
this.isExponentialNotation = isExponentialNotation;
|
this.isExponentialNotation = isExponentialNotation;
|
||||||
@ -56,90 +76,145 @@ public class SaveCSVWorker extends SwingWorker<Void, Void> {
|
|||||||
this.simulationComments = simulationComments;
|
this.simulationComments = simulationComments;
|
||||||
this.fieldComments = fieldComments;
|
this.fieldComments = fieldComments;
|
||||||
this.eventComments = eventComments;
|
this.eventComments = eventComments;
|
||||||
|
this.isCAData = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constructor for CA data
|
||||||
|
public SaveCSVWorker(File file, CAParameters parameters, CADataBranch branch,
|
||||||
|
CADomainDataType domainDataType, CADataType[] fields,
|
||||||
|
Map<CADataType, List<RocketComponent>> components, Unit[] units,
|
||||||
|
String fieldSeparator, int decimalPlaces, boolean isExponentialNotation,
|
||||||
|
String commentStarter, boolean analysisComments, boolean fieldDescriptions) {
|
||||||
|
this.file = file;
|
||||||
|
this.caParameters = parameters;
|
||||||
|
this.caDataBranch = branch;
|
||||||
|
this.caDomainDataType = domainDataType;
|
||||||
|
this.caDataFields = fields;
|
||||||
|
this.caComponents = components;
|
||||||
|
this.caUnits = units;
|
||||||
|
this.fieldSeparator = fieldSeparator;
|
||||||
|
this.decimalPlaces = decimalPlaces;
|
||||||
|
this.isExponentialNotation = isExponentialNotation;
|
||||||
|
this.commentStarter = commentStarter;
|
||||||
|
this.analysisComments = analysisComments;
|
||||||
|
this.fieldDescriptions = fieldDescriptions;
|
||||||
|
this.isCAData = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground() throws Exception {
|
protected Void doInBackground() throws Exception {
|
||||||
|
int estimate = BYTES_PER_FIELD_PER_POINT * (isCAData ? caDataFields.length : flightDataFields.length) *
|
||||||
int estimate = BYTES_PER_FIELD_PER_POINT * fields.length * branch.getLength();
|
(isCAData ? caDataBranch.getLength() : flightDataBranch.getLength());
|
||||||
estimate = Math.max(estimate, 1000);
|
estimate = Math.max(estimate, 1000);
|
||||||
|
|
||||||
// Create the ProgressOutputStream that provides progress estimates
|
try (ProgressOutputStream os = new ProgressOutputStream(
|
||||||
@SuppressWarnings("resource")
|
new BufferedOutputStream(new FileOutputStream(file)),
|
||||||
ProgressOutputStream os = new ProgressOutputStream(
|
|
||||||
new BufferedOutputStream(new FileOutputStream(file)),
|
|
||||||
estimate, this) {
|
estimate, this) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setProgress(int progress) {
|
protected void setProgress(int progress) {
|
||||||
SaveCSVWorker.this.setProgress(progress);
|
SaveCSVWorker.this.setProgress(progress);
|
||||||
}
|
}
|
||||||
|
}) {
|
||||||
};
|
if (isCAData) {
|
||||||
|
CSVExport.exportCSV(os, caParameters, caDataBranch, caDomainDataType, caDataFields, caComponents, caUnits,
|
||||||
try {
|
fieldSeparator, decimalPlaces, isExponentialNotation, analysisComments, fieldDescriptions, commentStarter);
|
||||||
CSVExport.exportCSV(os, simulation, branch, fields, units, fieldSeparator, decimalPlaces, isExponentialNotation,
|
} else {
|
||||||
commentStarter, simulationComments, fieldComments, eventComments);
|
CSVExport.exportCSV(os, simulation, flightDataBranch, flightDataFields, flightDataUnits, fieldSeparator,
|
||||||
} finally {
|
decimalPlaces, isExponentialNotation, commentStarter, simulationComments, fieldComments, eventComments);
|
||||||
try {
|
|
||||||
os.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Application.getExceptionHandler().handleErrorCondition("Error closing file", e);
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Application.getExceptionHandler().handleErrorCondition("Error writing file", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean export(File file, Simulation simulation, FlightDataBranch branch,
|
public static boolean exportSimulationData(File file, Simulation simulation, FlightDataBranch branch,
|
||||||
FlightDataType[] fields, Unit[] units, String fieldSeparator,
|
FlightDataType[] fields, Unit[] units, String fieldSeparator,
|
||||||
String commentStarter, boolean simulationComments,
|
String commentStarter, boolean simulationComments,
|
||||||
boolean fieldComments, boolean eventComments, Window parent) {
|
boolean fieldComments, boolean eventComments, Window parent) {
|
||||||
return export(file, simulation, branch, fields, units, fieldSeparator, TextUtil.DEFAULT_DECIMAL_PLACES, true,
|
return exportSimulationData(file, simulation, branch, fields, units, fieldSeparator, TextUtil.DEFAULT_DECIMAL_PLACES, true,
|
||||||
commentStarter, simulationComments, fieldComments, eventComments, parent);
|
commentStarter, simulationComments, fieldComments, eventComments, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports a CSV file using a progress dialog if necessary.
|
* Exports a CSV file using a progress dialog if necessary.
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if the save was successful, <code>false</code> otherwise.
|
* @return <code>true</code> if the save was successful, <code>false</code> otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean export(File file, Simulation simulation, FlightDataBranch branch,
|
public static boolean exportSimulationData(File file, Simulation simulation, FlightDataBranch branch,
|
||||||
FlightDataType[] fields, Unit[] units, String fieldSeparator, int decimalPlaces,
|
FlightDataType[] fields, Unit[] units, String fieldSeparator, int decimalPlaces,
|
||||||
boolean isExponentialNotation, String commentStarter, boolean simulationComments,
|
boolean isExponentialNotation, String commentStarter, boolean simulationComments,
|
||||||
boolean fieldComments, boolean eventComments, Window parent) {
|
boolean fieldComments, boolean eventComments, Window parent) {
|
||||||
|
|
||||||
|
|
||||||
SaveCSVWorker worker = new SaveCSVWorker(file, simulation, branch, fields, units,
|
SaveCSVWorker worker = new SaveCSVWorker(file, simulation, branch, fields, units,
|
||||||
fieldSeparator, decimalPlaces, isExponentialNotation, commentStarter, simulationComments,
|
fieldSeparator, decimalPlaces, isExponentialNotation, commentStarter, simulationComments,
|
||||||
fieldComments, eventComments);
|
fieldComments, eventComments);
|
||||||
|
|
||||||
if (!SwingWorkerDialog.runWorker(parent, "Exporting flight data",
|
if (!SwingWorkerDialog.runWorker(parent, "Exporting flight data",
|
||||||
"Writing " + file.getName() + "...", worker)) {
|
"Writing " + file.getName() + "...", worker)) {
|
||||||
|
|
||||||
// User cancelled the save
|
// User cancelled the save
|
||||||
file.delete();
|
file.delete();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
worker.get();
|
worker.get();
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
Throwable cause = e.getCause();
|
Throwable cause = e.getCause();
|
||||||
|
|
||||||
if (cause instanceof IOException) {
|
if (cause instanceof IOException) {
|
||||||
JOptionPane.showMessageDialog(parent, new String[] {
|
JOptionPane.showMessageDialog(parent, new String[] {
|
||||||
"An I/O error occurred while saving:",
|
"An I/O error occurred while saving:",
|
||||||
e.getMessage() }, "Saving failed", JOptionPane.ERROR_MESSAGE);
|
e.getMessage() }, "Saving failed", JOptionPane.ERROR_MESSAGE);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw new BugException("Unknown error when saving file", e);
|
throw new BugException("Unknown error when saving file", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new BugException("EDT was interrupted", e);
|
throw new BugException("EDT was interrupted", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// New export method for CA data
|
||||||
|
public static boolean exportCAData(File file, CAParameters parameters, CADataBranch branch,
|
||||||
|
CADomainDataType domainDataType, CADataType[] fields,
|
||||||
|
Map<CADataType, List<RocketComponent>> components, Unit[] units,
|
||||||
|
String fieldSeparator, int decimalPlaces, boolean isExponentialNotation,
|
||||||
|
String commentStarter, boolean analysisComments, boolean fieldDescriptions,
|
||||||
|
Window parent) {
|
||||||
|
SaveCSVWorker worker = new SaveCSVWorker(file, parameters, branch, domainDataType, fields, components, units,
|
||||||
|
fieldSeparator, decimalPlaces, isExponentialNotation, commentStarter, analysisComments, fieldDescriptions);
|
||||||
|
|
||||||
|
if (!SwingWorkerDialog.runWorker(parent, "Exporting component analysis data",
|
||||||
|
"Writing " + file.getName() + "...", worker)) {
|
||||||
|
// User cancelled the save
|
||||||
|
file.delete();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
worker.get();
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
Throwable cause = e.getCause();
|
||||||
|
|
||||||
|
if (cause instanceof IOException) {
|
||||||
|
JOptionPane.showMessageDialog(parent, new String[] {
|
||||||
|
"An I/O error occurred while saving:",
|
||||||
|
e.getMessage() }, "Saving failed", JOptionPane.ERROR_MESSAGE);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
throw new BugException("Unknown error when saving file", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new BugException("EDT was interrupted", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user