Add RocketComponent selector in CAExportPanel
This commit is contained in:
		
							parent
							
								
									88f7c7e18d
								
							
						
					
					
						commit
						73981839e6
					
				@ -966,6 +966,9 @@ CAPlotExportDialog.lbl.Delta.ttip = Step size (increments) for the parameter swe
 | 
				
			|||||||
CAPlotExportDialog.tab.Plot = Plot
 | 
					CAPlotExportDialog.tab.Plot = Plot
 | 
				
			||||||
CAPlotExportDialog.tab.Export = Export
 | 
					CAPlotExportDialog.tab.Export = Export
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! CAExportPanel
 | 
				
			||||||
 | 
					CAExportPanel.Col.Components = Components
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! CADataTypeGroup
 | 
					! CADataTypeGroup
 | 
				
			||||||
CADataTypeGroup.DOMAIN = Domain Parameter
 | 
					CADataTypeGroup.DOMAIN = Domain Parameter
 | 
				
			||||||
CADataTypeGroup.DRAG = Drag Characteristics
 | 
					CADataTypeGroup.DRAG = Drag Characteristics
 | 
				
			||||||
 | 
				
			|||||||
@ -42,7 +42,7 @@ public class CsvOptionPanel extends JPanel {
 | 
				
			|||||||
	 * @param includeComments	a list of comment inclusion options to provide;
 | 
						 * @param includeComments	a list of comment inclusion options to provide;
 | 
				
			||||||
	 * 							every second item is the option name and every second the tooltip
 | 
						 * 							every second item is the option name and every second the tooltip
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public CsvOptionPanel(Class<?> baseClass, String... includeComments) {
 | 
						public CsvOptionPanel(Class<?> baseClass, boolean placeOnNewRows, String... includeComments) {
 | 
				
			||||||
		super(new MigLayout("fill, insets 0"));
 | 
							super(new MigLayout("fill, insets 0"));
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		this.baseClassName = baseClass.getSimpleName();
 | 
							this.baseClassName = baseClass.getSimpleName();
 | 
				
			||||||
@ -88,7 +88,11 @@ public class CsvOptionPanel extends JPanel {
 | 
				
			|||||||
		exponentialNotationCheckbox.setSelected(Application.getPreferences().getBoolean(ApplicationPreferences.EXPORT_EXPONENTIAL_NOTATION, true));
 | 
							exponentialNotationCheckbox.setSelected(Application.getPreferences().getBoolean(ApplicationPreferences.EXPORT_EXPONENTIAL_NOTATION, true));
 | 
				
			||||||
		panel.add(exponentialNotationCheckbox);
 | 
							panel.add(exponentialNotationCheckbox);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.add(panel, "growx, wrap unrel");
 | 
							if (placeOnNewRows) {
 | 
				
			||||||
 | 
								this.add(panel, "growx, wrap unrel");
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								this.add(panel, "growx, gapright unrel");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -120,8 +124,16 @@ public class CsvOptionPanel extends JPanel {
 | 
				
			|||||||
		commentCharacter.setSelectedItem(Application.getPreferences().getString(ApplicationPreferences.EXPORT_COMMENT_CHARACTER, "#"));
 | 
							commentCharacter.setSelectedItem(Application.getPreferences().getString(ApplicationPreferences.EXPORT_COMMENT_CHARACTER, "#"));
 | 
				
			||||||
		commentCharacter.setToolTipText(tip);
 | 
							commentCharacter.setToolTipText(tip);
 | 
				
			||||||
		panel.add(commentCharacter, "growx");
 | 
							panel.add(commentCharacter, "growx");
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		this.add(panel, "growx, wrap");
 | 
							if (placeOnNewRows) {
 | 
				
			||||||
 | 
								this.add(panel, "growx, wrap");
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								this.add(panel, "growx");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public CsvOptionPanel(Class<?> baseClass, String... includeComments) {
 | 
				
			||||||
 | 
							this(baseClass, true, includeComments);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
package info.openrocket.swing.gui.dialogs.componentanalysis;
 | 
					package info.openrocket.swing.gui.dialogs.componentanalysis;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import info.openrocket.core.l10n.Translator;
 | 
					import info.openrocket.core.l10n.Translator;
 | 
				
			||||||
 | 
					import info.openrocket.core.rocketcomponent.RocketComponent;
 | 
				
			||||||
import info.openrocket.core.startup.Application;
 | 
					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;
 | 
				
			||||||
@ -9,33 +10,96 @@ 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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.swing.AbstractCellEditor;
 | 
				
			||||||
 | 
					import javax.swing.BorderFactory;
 | 
				
			||||||
 | 
					import javax.swing.JCheckBox;
 | 
				
			||||||
 | 
					import javax.swing.JComponent;
 | 
				
			||||||
import javax.swing.JFileChooser;
 | 
					import javax.swing.JFileChooser;
 | 
				
			||||||
 | 
					import javax.swing.JLabel;
 | 
				
			||||||
 | 
					import javax.swing.JPanel;
 | 
				
			||||||
 | 
					import javax.swing.JTable;
 | 
				
			||||||
 | 
					import javax.swing.table.DefaultTableCellRenderer;
 | 
				
			||||||
 | 
					import javax.swing.table.TableCellEditor;
 | 
				
			||||||
 | 
					import javax.swing.table.TableCellRenderer;
 | 
				
			||||||
 | 
					import javax.swing.table.TableColumn;
 | 
				
			||||||
 | 
					import java.awt.Color;
 | 
				
			||||||
import java.awt.Component;
 | 
					import java.awt.Component;
 | 
				
			||||||
 | 
					import java.awt.Graphics;
 | 
				
			||||||
 | 
					import java.awt.GridBagConstraints;
 | 
				
			||||||
 | 
					import java.awt.GridBagLayout;
 | 
				
			||||||
 | 
					import java.awt.Insets;
 | 
				
			||||||
 | 
					import java.awt.event.ItemEvent;
 | 
				
			||||||
 | 
					import java.awt.event.ItemListener;
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.HashMap;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					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 OPTION_FIELD_DESCRIPTIONS = 0;
 | 
				
			||||||
 | 
						private static final int FIXED_COMPONENT_COLUMN_WIDTH = 500;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private CAExportPanel(CADataType[] types,
 | 
						private final List<Map<RocketComponent, Boolean>> selectedComponents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private CAExportPanel(ComponentAnalysisPlotExportPanel parent, CADataType[] types,
 | 
				
			||||||
						  boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
 | 
											  boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
 | 
				
			||||||
		super(types, selected, csvOptions, extraComponents);
 | 
							super(types, selected, csvOptions, true, extraComponents);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							selectedComponents = new ArrayList<>(types.length);
 | 
				
			||||||
 | 
							Map<RocketComponent, Boolean> componentSelectedMap;
 | 
				
			||||||
 | 
							List<RocketComponent> components;
 | 
				
			||||||
 | 
							for (CADataType type : types) {
 | 
				
			||||||
 | 
								components = parent.getComponentsForType(type);
 | 
				
			||||||
 | 
								componentSelectedMap = new HashMap<>(components.size());
 | 
				
			||||||
 | 
								for (int i = 0; i < components.size(); i++) {
 | 
				
			||||||
 | 
									// Select the first component by default
 | 
				
			||||||
 | 
									componentSelectedMap.put(components.get(i), i == 0);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								selectedComponents.add(componentSelectedMap);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Set row heights dynamically
 | 
				
			||||||
 | 
							for (int row = 0; row < table.getRowCount(); row++) {
 | 
				
			||||||
 | 
								int numComponents = ((Map<?, ?>) table.getValueAt(row, 3)).size();
 | 
				
			||||||
 | 
								double correctNumComponents = Math.ceil(numComponents / 3.0);  // 3 components per row
 | 
				
			||||||
 | 
								double height = Math.round(correctNumComponents * 25) + 10;  // 25 pixels per component + 10 pixel margin
 | 
				
			||||||
 | 
								int rowHeight = Math.max(table.getRowHeight(), (int) height);
 | 
				
			||||||
 | 
								table.setRowHeight(row, rowHeight);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static CAExportPanel create(CADataType[] types) {
 | 
						public static CAExportPanel create(ComponentAnalysisPlotExportPanel parent, CADataType[] types) {
 | 
				
			||||||
		boolean[] selected = new boolean[types.length];
 | 
							boolean[] selected = new boolean[types.length];
 | 
				
			||||||
		for (int i = 0; i < types.length; i++) {
 | 
							for (int i = 0; i < types.length; i++) {
 | 
				
			||||||
			selected[i] = ((SwingPreferences) Application.getPreferences()).isComponentAnalysisDataTypeExportSelected(types[i]);
 | 
								selected[i] = ((SwingPreferences) Application.getPreferences()).isComponentAnalysisDataTypeExportSelected(types[i]);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		CsvOptionPanel csvOptions = new CsvOptionPanel(CAExportPanel.class,
 | 
							CsvOptionPanel csvOptions = new CsvOptionPanel(CAExportPanel.class, false,
 | 
				
			||||||
				trans.get("SimExpPan.checkbox.Includefielddesc"),
 | 
									trans.get("SimExpPan.checkbox.Includefielddesc"),
 | 
				
			||||||
				trans.get("SimExpPan.checkbox.ttip.Includefielddesc"));
 | 
									trans.get("SimExpPan.checkbox.ttip.Includefielddesc"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return new CAExportPanel(types, selected, csvOptions);
 | 
							return new CAExportPanel(parent, types, selected, csvOptions);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected void initializeTable(CADataType[] types) {
 | 
				
			||||||
 | 
							super.initializeTable(types);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Set custom renderers for each column
 | 
				
			||||||
 | 
							table.getColumnModel().getColumn(0).setCellRenderer(new CheckBoxRenderer());
 | 
				
			||||||
 | 
							table.getColumnModel().getColumn(1).setCellRenderer(new LeftAlignedRenderer());
 | 
				
			||||||
 | 
							table.getColumnModel().getColumn(2).setCellRenderer(new LeftAlignedRenderer());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TableColumn componentColumn = table.getColumnModel().getColumn(3);
 | 
				
			||||||
 | 
							componentColumn.setCellRenderer(new ComponentCheckBoxRenderer());
 | 
				
			||||||
 | 
							componentColumn.setCellEditor(new ComponentCheckBoxEditor());
 | 
				
			||||||
 | 
							componentColumn.setPreferredWidth(FIXED_COMPONENT_COLUMN_WIDTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Set specific client properties for FlatLaf
 | 
				
			||||||
 | 
							table.setShowHorizontalLines(true);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
@ -98,4 +162,278 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						protected CSVExportPanel<CADataType>.SelectionTableModel createTableModel() {
 | 
				
			||||||
 | 
							return new CASelectionTableModel();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected class CASelectionTableModel extends SelectionTableModel {
 | 
				
			||||||
 | 
							private static final int COMPONENTS = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public int getColumnCount() {
 | 
				
			||||||
 | 
								return 4;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public String getColumnName(int column) {
 | 
				
			||||||
 | 
								//// Components
 | 
				
			||||||
 | 
								if (column == COMPONENTS) {
 | 
				
			||||||
 | 
									return trans.get("CAExportPanel.Col.Components");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return super.getColumnName(column);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public Class<?> getColumnClass(int column) {
 | 
				
			||||||
 | 
								//// Components
 | 
				
			||||||
 | 
								if (column == COMPONENTS) {
 | 
				
			||||||
 | 
									return Map.class;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return super.getColumnClass(column);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public Object getValueAt(int row, int column) {
 | 
				
			||||||
 | 
								if (column == COMPONENTS) {
 | 
				
			||||||
 | 
									return selectedComponents.get(row);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return super.getValueAt(row, column);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public void setValueAt(Object value, int row, int column) {
 | 
				
			||||||
 | 
								if (column == COMPONENTS) {
 | 
				
			||||||
 | 
									selectedComponents.set(row, (Map<RocketComponent, Boolean>) value);
 | 
				
			||||||
 | 
									fireTableCellUpdated(row, column);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									super.setValueAt(value, row, column);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public boolean isCellEditable(int row, int column) {
 | 
				
			||||||
 | 
								if (column == COMPONENTS) {
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return super.isCellEditable(row, column);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static class CheckBoxRenderer extends JCheckBox implements TableCellRenderer {
 | 
				
			||||||
 | 
							public CheckBoxRenderer() {
 | 
				
			||||||
 | 
								setHorizontalAlignment(JLabel.CENTER);
 | 
				
			||||||
 | 
								setVerticalAlignment(JLabel.TOP);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
 | 
				
			||||||
 | 
								setSelected((Boolean) value);
 | 
				
			||||||
 | 
								setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
 | 
				
			||||||
 | 
								setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
 | 
				
			||||||
 | 
								setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); // Add top padding
 | 
				
			||||||
 | 
								return this;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static class LeftAlignedRenderer extends DefaultTableCellRenderer {
 | 
				
			||||||
 | 
							public LeftAlignedRenderer() {
 | 
				
			||||||
 | 
								setHorizontalAlignment(JLabel.LEFT);
 | 
				
			||||||
 | 
								setVerticalAlignment(JLabel.TOP);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
 | 
				
			||||||
 | 
								Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
 | 
				
			||||||
 | 
								c.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
 | 
				
			||||||
 | 
								c.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
 | 
				
			||||||
 | 
								((JComponent) c).setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0)); // Add top and left padding
 | 
				
			||||||
 | 
								return c;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static class ComponentCheckBoxRenderer implements TableCellRenderer {
 | 
				
			||||||
 | 
							private ComponentCheckBoxPanel panel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
 | 
				
			||||||
 | 
								if (!(value instanceof Map)) {
 | 
				
			||||||
 | 
									JLabel errorLabel = new JLabel("Invalid data");
 | 
				
			||||||
 | 
									errorLabel.setForeground(Color.RED);
 | 
				
			||||||
 | 
									return errorLabel;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								@SuppressWarnings("unchecked")
 | 
				
			||||||
 | 
								Map<RocketComponent, Boolean> componentMap = (Map<RocketComponent, Boolean>) value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (panel == null) {
 | 
				
			||||||
 | 
									panel = new ComponentCheckBoxPanel(componentMap);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									panel.updateComponentStates(componentMap);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								panel.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
 | 
				
			||||||
 | 
								panel.setGridColor(table.getGridColor());
 | 
				
			||||||
 | 
								panel.setSelected(isSelected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return panel;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static class ComponentCheckBoxPanel extends JPanel {
 | 
				
			||||||
 | 
							private final Map<RocketComponent, JCheckBox> checkBoxMap = new HashMap<>();
 | 
				
			||||||
 | 
							private final ItemListener checkBoxListener;
 | 
				
			||||||
 | 
							private final AtomicBoolean updatingState = new AtomicBoolean(false);
 | 
				
			||||||
 | 
							private Color gridColor = Color.GRAY;
 | 
				
			||||||
 | 
							private boolean isSelected = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public ComponentCheckBoxPanel(Map<RocketComponent, Boolean> componentMap) {
 | 
				
			||||||
 | 
								setLayout(new GridBagLayout());
 | 
				
			||||||
 | 
								GridBagConstraints gbc = new GridBagConstraints();
 | 
				
			||||||
 | 
								gbc.anchor = GridBagConstraints.NORTHWEST;
 | 
				
			||||||
 | 
								gbc.fill = GridBagConstraints.HORIZONTAL;
 | 
				
			||||||
 | 
								gbc.weightx = 1.0;
 | 
				
			||||||
 | 
								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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Add an empty component to push everything to the top-left
 | 
				
			||||||
 | 
								gbc.gridx = 0;
 | 
				
			||||||
 | 
								gbc.gridy = (componentMap.size() + 2) / 3 + 1;
 | 
				
			||||||
 | 
								gbc.weighty = 1.0;
 | 
				
			||||||
 | 
								gbc.fill = GridBagConstraints.BOTH;
 | 
				
			||||||
 | 
								add(new JPanel(), gbc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Ensure at least one checkbox is selected
 | 
				
			||||||
 | 
								if (checkBoxMap.values().stream().noneMatch(JCheckBox::isSelected) && !checkBoxMap.isEmpty()) {
 | 
				
			||||||
 | 
									checkBoxMap.values().iterator().next().setSelected(true);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void createCheckBoxes(Map<RocketComponent, Boolean> componentMap, GridBagConstraints gbc) {
 | 
				
			||||||
 | 
								int row = 0;
 | 
				
			||||||
 | 
								int col = 0;
 | 
				
			||||||
 | 
								for (Map.Entry<RocketComponent, Boolean> entry : componentMap.entrySet()) {
 | 
				
			||||||
 | 
									RocketComponent component = entry.getKey();
 | 
				
			||||||
 | 
									Boolean isSelected = entry.getValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Skip null components
 | 
				
			||||||
 | 
									if (component == null) {
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									String componentName = component.getName();
 | 
				
			||||||
 | 
									// Use a default name if getName() returns null
 | 
				
			||||||
 | 
									if (componentName == null) {
 | 
				
			||||||
 | 
										componentName = "Unnamed Component";
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									JCheckBox checkBox = new JCheckBox(componentName, isSelected != null && isSelected);
 | 
				
			||||||
 | 
									checkBox.setOpaque(false);
 | 
				
			||||||
 | 
									checkBox.setMargin(new Insets(0, 0, 0, 0));
 | 
				
			||||||
 | 
									checkBox.addItemListener(checkBoxListener);
 | 
				
			||||||
 | 
									checkBoxMap.put(component, checkBox);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									gbc.gridx = col;
 | 
				
			||||||
 | 
									gbc.gridy = row;
 | 
				
			||||||
 | 
									add(checkBox, gbc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									col++;
 | 
				
			||||||
 | 
									if (col > 2) {
 | 
				
			||||||
 | 
										col = 0;
 | 
				
			||||||
 | 
										row++;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void updateComponentStates(Map<RocketComponent, Boolean> newStates) {
 | 
				
			||||||
 | 
								updatingState.set(true);
 | 
				
			||||||
 | 
								try {
 | 
				
			||||||
 | 
									for (Map.Entry<RocketComponent, Boolean> entry : newStates.entrySet()) {
 | 
				
			||||||
 | 
										JCheckBox checkBox = checkBoxMap.get(entry.getKey());
 | 
				
			||||||
 | 
										if (checkBox != null) {
 | 
				
			||||||
 | 
											checkBox.setSelected(entry.getValue());
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} finally {
 | 
				
			||||||
 | 
									updatingState.set(false);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public Map<RocketComponent, Boolean> getComponentStates() {
 | 
				
			||||||
 | 
								return checkBoxMap.entrySet().stream()
 | 
				
			||||||
 | 
										.collect(HashMap::new,
 | 
				
			||||||
 | 
												(m, e) -> m.put(e.getKey(), e.getValue().isSelected()),
 | 
				
			||||||
 | 
												HashMap::putAll);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void setGridColor(Color color) {
 | 
				
			||||||
 | 
								this.gridColor = color;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void setSelected(boolean selected) {
 | 
				
			||||||
 | 
								this.isSelected = selected;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							protected void paintComponent(Graphics g) {
 | 
				
			||||||
 | 
								super.paintComponent(g);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Draw the bottom border
 | 
				
			||||||
 | 
								g.setColor(gridColor);
 | 
				
			||||||
 | 
								g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// If selected, draw a slight highlight
 | 
				
			||||||
 | 
								if (isSelected) {
 | 
				
			||||||
 | 
									g.setColor(new Color(0, 0, 255, 30)); // Semi-transparent blue
 | 
				
			||||||
 | 
									g.fillRect(0, 0, getWidth(), getHeight() - 1);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static class ComponentCheckBoxEditor extends AbstractCellEditor implements TableCellEditor {
 | 
				
			||||||
 | 
							private ComponentCheckBoxPanel panel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
 | 
				
			||||||
 | 
								if (!(value instanceof Map)) {
 | 
				
			||||||
 | 
									// Return a default component if value is not a Map
 | 
				
			||||||
 | 
									JLabel errorLabel = new JLabel("Invalid data");
 | 
				
			||||||
 | 
									errorLabel.setForeground(Color.RED);
 | 
				
			||||||
 | 
									return errorLabel;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								@SuppressWarnings("unchecked")
 | 
				
			||||||
 | 
								Map<RocketComponent, Boolean> componentMap = (Map<RocketComponent, Boolean>) value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (panel == null) {
 | 
				
			||||||
 | 
									panel = new ComponentCheckBoxPanel(componentMap);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									panel.updateComponentStates(componentMap);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								panel.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
 | 
				
			||||||
 | 
								return panel;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public Object getCellEditorValue() {
 | 
				
			||||||
 | 
								return panel.getComponentStates();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -58,7 +58,7 @@ public class ComponentAnalysisPlotExportPanel extends JPanel {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	public ComponentAnalysisPlotExportPanel(ComponentAnalysisDialog parent, CAParameters parameters,
 | 
						public ComponentAnalysisPlotExportPanel(ComponentAnalysisDialog parent, CAParameters parameters,
 | 
				
			||||||
											AerodynamicCalculator aerodynamicCalculator, Rocket rocket) {
 | 
																AerodynamicCalculator aerodynamicCalculator, Rocket rocket) {
 | 
				
			||||||
		super(new MigLayout("fill, height 500px"));
 | 
							super(new MigLayout("fill, height 700px"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.parent = parent;
 | 
							this.parent = parent;
 | 
				
			||||||
		this.parameters = parameters;
 | 
							this.parameters = parameters;
 | 
				
			||||||
@ -80,7 +80,7 @@ public class ComponentAnalysisPlotExportPanel extends JPanel {
 | 
				
			|||||||
		this.tabbedPane.addTab(trans.get("CAPlotExportDialog.tab.Plot"), null, this.plotTab);
 | 
							this.tabbedPane.addTab(trans.get("CAPlotExportDialog.tab.Plot"), null, this.plotTab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//// Export data
 | 
							//// Export data
 | 
				
			||||||
		this.exportTab = CAExportPanel.create(types);
 | 
							this.exportTab = CAExportPanel.create(this, types);
 | 
				
			||||||
		this.tabbedPane.addTab(trans.get("CAPlotExportDialog.tab.Export"), null, this.exportTab);
 | 
							this.tabbedPane.addTab(trans.get("CAPlotExportDialog.tab.Export"), null, this.exportTab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Create the OK button
 | 
							// Create the OK button
 | 
				
			||||||
 | 
				
			|||||||
@ -32,8 +32,8 @@ public class CSVExportPanel<T extends UnitValue> extends JPanel {
 | 
				
			|||||||
	protected static final String SPACE = "SPACE";
 | 
						protected static final String SPACE = "SPACE";
 | 
				
			||||||
	protected static final String TAB = "TAB";
 | 
						protected static final String TAB = "TAB";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final JTable table;
 | 
						protected final JTable table;
 | 
				
			||||||
	private final SelectionTableModel tableModel;
 | 
						protected final SelectionTableModel tableModel;
 | 
				
			||||||
	private final JLabel selectedCountLabel;
 | 
						private final JLabel selectedCountLabel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected final boolean[] selected;
 | 
						protected final boolean[] selected;
 | 
				
			||||||
@ -42,7 +42,7 @@ public class CSVExportPanel<T extends UnitValue> extends JPanel {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	protected final CsvOptionPanel csvOptions;
 | 
						protected final CsvOptionPanel csvOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public CSVExportPanel(T[] types, boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
 | 
						public CSVExportPanel(T[] types, boolean[] selected, CsvOptionPanel csvOptions, boolean separateRowForTable, Component... extraComponents) {
 | 
				
			||||||
		super(new MigLayout("fill, flowy"));
 | 
							super(new MigLayout("fill, flowy"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.types = types;
 | 
							this.types = types;
 | 
				
			||||||
@ -59,39 +59,9 @@ public class CSVExportPanel<T extends UnitValue> extends JPanel {
 | 
				
			|||||||
		JButton button;
 | 
							JButton button;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Set up the variable selection table
 | 
							// Set up the variable selection table
 | 
				
			||||||
		tableModel = new SelectionTableModel();
 | 
							tableModel = createTableModel();
 | 
				
			||||||
		table = new JTable(tableModel);
 | 
							table = new JTable(tableModel);
 | 
				
			||||||
		table.setDefaultRenderer(Object.class,
 | 
							initializeTable(types);
 | 
				
			||||||
				new SelectionBackgroundCellRenderer(table.getDefaultRenderer(Object.class)));
 | 
					 | 
				
			||||||
		table.setDefaultRenderer(Boolean.class,
 | 
					 | 
				
			||||||
				new SelectionBackgroundCellRenderer(table.getDefaultRenderer(Boolean.class)));
 | 
					 | 
				
			||||||
		table.setRowSelectionAllowed(false);
 | 
					 | 
				
			||||||
		table.setColumnSelectionAllowed(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		table.setDefaultEditor(Unit.class, new UnitCellEditor() {
 | 
					 | 
				
			||||||
			private static final long serialVersionUID = 1088570433902420935L;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			@Override
 | 
					 | 
				
			||||||
			protected UnitGroup getUnitGroup(Unit value, int row, int column) {
 | 
					 | 
				
			||||||
				return types[row].getUnitGroup();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Set column widths
 | 
					 | 
				
			||||||
		TableColumnModel columnModel = table.getColumnModel();
 | 
					 | 
				
			||||||
		TableColumn col = columnModel.getColumn(0);
 | 
					 | 
				
			||||||
		int w = table.getRowHeight();
 | 
					 | 
				
			||||||
		col.setMinWidth(w);
 | 
					 | 
				
			||||||
		col.setPreferredWidth(w);
 | 
					 | 
				
			||||||
		col.setMaxWidth(w);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		col = columnModel.getColumn(1);
 | 
					 | 
				
			||||||
		col.setPreferredWidth(200);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		col = columnModel.getColumn(2);
 | 
					 | 
				
			||||||
		col.setPreferredWidth(100);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		table.addMouseListener(new GUIUtil.BooleanTableClickListener(table));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Add table
 | 
							// Add table
 | 
				
			||||||
		panel = new JPanel(new MigLayout("fill"));
 | 
							panel = new JPanel(new MigLayout("fill"));
 | 
				
			||||||
@ -124,21 +94,77 @@ public class CSVExportPanel<T extends UnitValue> extends JPanel {
 | 
				
			|||||||
		updateSelectedCount();
 | 
							updateSelectedCount();
 | 
				
			||||||
		panel.add(selectedCountLabel);
 | 
							panel.add(selectedCountLabel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.add(panel, "grow 100, wrap");
 | 
							if (separateRowForTable) {
 | 
				
			||||||
 | 
								this.add(panel, "spanx, grow 100, wrap");
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								this.add(panel, "grow 100, wrap");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Add CSV options
 | 
							// Add CSV options
 | 
				
			||||||
		this.add(csvOptions, "spany, split, growx 1");
 | 
							if (separateRowForTable) {
 | 
				
			||||||
 | 
								this.add(csvOptions, "grow 1");
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								this.add(csvOptions, "spany, split, growx 1");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//// Add extra widgets
 | 
							//// Add extra widgets
 | 
				
			||||||
		if (extraComponents != null) {
 | 
							if (extraComponents != null) {
 | 
				
			||||||
			for (Component c : extraComponents) {
 | 
								for (Component c : extraComponents) {
 | 
				
			||||||
				this.add(c, "spany, split, growx 1");
 | 
									if (separateRowForTable) {
 | 
				
			||||||
 | 
										this.add(c, "grow 1");
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										this.add(c, "spany, split, growx 1");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Space-filling panel
 | 
							// Space-filling panel
 | 
				
			||||||
		panel = new JPanel();
 | 
							if (!separateRowForTable) {
 | 
				
			||||||
		this.add(panel, "width 1, height 1, grow 1");
 | 
								panel = new JPanel();
 | 
				
			||||||
 | 
								this.add(panel, "width 1, height 1, grow 1");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public CSVExportPanel(T[] types, boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
 | 
				
			||||||
 | 
							this(types, selected, csvOptions, false, extraComponents);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected SelectionTableModel createTableModel() {
 | 
				
			||||||
 | 
							return new SelectionTableModel();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected void initializeTable(T[] types) {
 | 
				
			||||||
 | 
							table.setDefaultRenderer(Object.class,
 | 
				
			||||||
 | 
									new SelectionBackgroundCellRenderer(table.getDefaultRenderer(Object.class)));
 | 
				
			||||||
 | 
							table.setDefaultRenderer(Boolean.class,
 | 
				
			||||||
 | 
									new SelectionBackgroundCellRenderer(table.getDefaultRenderer(Boolean.class)));
 | 
				
			||||||
 | 
							table.setRowSelectionAllowed(false);
 | 
				
			||||||
 | 
							table.setColumnSelectionAllowed(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							table.setDefaultEditor(Unit.class, new UnitCellEditor() {
 | 
				
			||||||
 | 
								private static final long serialVersionUID = 1088570433902420935L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								@Override
 | 
				
			||||||
 | 
								protected UnitGroup getUnitGroup(Unit value, int row, int column) {
 | 
				
			||||||
 | 
									return types[row].getUnitGroup();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Set column widths
 | 
				
			||||||
 | 
							TableColumnModel columnModel = table.getColumnModel();
 | 
				
			||||||
 | 
							TableColumn col = columnModel.getColumn(0);
 | 
				
			||||||
 | 
							int w = table.getRowHeight();
 | 
				
			||||||
 | 
							col.setMinWidth(w);
 | 
				
			||||||
 | 
							col.setPreferredWidth(w);
 | 
				
			||||||
 | 
							col.setMaxWidth(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							col = columnModel.getColumn(1);
 | 
				
			||||||
 | 
							col.setPreferredWidth(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							col = columnModel.getColumn(2);
 | 
				
			||||||
 | 
							col.setPreferredWidth(100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							table.addMouseListener(new GUIUtil.BooleanTableClickListener(table));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public boolean doExport() {
 | 
						public boolean doExport() {
 | 
				
			||||||
@ -171,11 +197,11 @@ public class CSVExportPanel<T extends UnitValue> extends JPanel {
 | 
				
			|||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * The table model for the variable selection.
 | 
						 * The table model for the variable selection.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	private class SelectionTableModel extends AbstractTableModel {
 | 
						protected class SelectionTableModel extends AbstractTableModel {
 | 
				
			||||||
		private static final long serialVersionUID = 493067422917621072L;
 | 
							private static final long serialVersionUID = 493067422917621072L;
 | 
				
			||||||
		private static final int SELECTED = 0;
 | 
							protected static final int SELECTED = 0;
 | 
				
			||||||
		private static final int NAME = 1;
 | 
							protected static final int NAME = 1;
 | 
				
			||||||
		private static final int UNIT = 2;
 | 
							protected static final int UNIT = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@Override
 | 
							@Override
 | 
				
			||||||
		public int getColumnCount() {
 | 
							public int getColumnCount() {
 | 
				
			||||||
@ -199,7 +225,6 @@ public class CSVExportPanel<T extends UnitValue> extends JPanel {
 | 
				
			|||||||
						trans.get("SimExpPan.Col.Unit");
 | 
											trans.get("SimExpPan.Col.Unit");
 | 
				
			||||||
				default -> throw new IndexOutOfBoundsException("column=" + column);
 | 
									default -> throw new IndexOutOfBoundsException("column=" + column);
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@Override
 | 
							@Override
 | 
				
			||||||
@ -214,14 +239,12 @@ public class CSVExportPanel<T extends UnitValue> extends JPanel {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		@Override
 | 
							@Override
 | 
				
			||||||
		public Object getValueAt(int row, int column) {
 | 
							public Object getValueAt(int row, int column) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
			return switch (column) {
 | 
								return switch (column) {
 | 
				
			||||||
				case SELECTED -> selected[row];
 | 
									case SELECTED -> selected[row];
 | 
				
			||||||
				case NAME -> types[row];
 | 
									case NAME -> types[row];
 | 
				
			||||||
				case UNIT -> units[row];
 | 
									case UNIT -> units[row];
 | 
				
			||||||
				default -> throw new IndexOutOfBoundsException("column=" + column);
 | 
									default -> throw new IndexOutOfBoundsException("column=" + column);
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@Override
 | 
							@Override
 | 
				
			||||||
@ -243,7 +266,6 @@ public class CSVExportPanel<T extends UnitValue> extends JPanel {
 | 
				
			|||||||
				default:
 | 
									default:
 | 
				
			||||||
					throw new IndexOutOfBoundsException("column=" + column);
 | 
										throw new IndexOutOfBoundsException("column=" + column);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@Override
 | 
							@Override
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user