[#24556] Combine sim settings & plot/export dialogs
This commit is contained in:
parent
921124e337
commit
addd81b799
@ -452,9 +452,10 @@ simedtdlg.but.delete = Delete
|
||||
simedtdlg.title.Editsim = Edit simulation
|
||||
simedtdlg.title.MultiSimEdit = Multi-simulation edit
|
||||
simedtdlg.title.MultiSimEdit.ttip = <html>You are editing the following simulations:<br>
|
||||
simedtdlg.lbl.Simname = Simulation name:
|
||||
simedtdlg.lbl.Simname = Name:
|
||||
simedtdlg.tab.Launchcond = Launch conditions
|
||||
simedtdlg.tab.Simopt = Simulation options
|
||||
simedtdlg.tab.Settings = Settings
|
||||
simedtdlg.tab.Plotdata = Plot data
|
||||
simedtdlg.tab.CustomExpressions = Custom expressions
|
||||
simedtdlg.tab.Exportdata = Export data
|
||||
@ -534,6 +535,10 @@ simedtdlg.IntensityDesc.High = High
|
||||
simedtdlg.IntensityDesc.Veryhigh = Very high
|
||||
simedtdlg.IntensityDesc.Extreme = Extreme
|
||||
|
||||
! SimulationConfigDialog
|
||||
SimulationConfigDialog.tab.plotDis.ttip = Plotting not supported for multi-simulation editing
|
||||
SimulationConfigDialog.tab.expDis.ttip = Exporting not supported for multi-simulation editing
|
||||
|
||||
SimulationExtension.airstart.name.alt = Air-start ({alt})
|
||||
SimulationExtension.airstart.name.altvel = Air-start ({alt}, {vel})
|
||||
SimulationExtension.javacode.name = Java code
|
||||
|
@ -321,7 +321,7 @@ simedtdlg.but.savedefault = Save as default
|
||||
simedtdlg.but.add = Add
|
||||
simedtdlg.but.delete = Delete
|
||||
simedtdlg.title.Editsim = Edit simulation
|
||||
simedtdlg.lbl.Simname = Simulation name:
|
||||
simedtdlg.lbl.Simname = Name:
|
||||
simedtdlg.tab.Launchcond = Launch conditions
|
||||
simedtdlg.tab.Simopt = Simulation options
|
||||
simedtdlg.tab.Plotdata = Plot data
|
||||
|
@ -45,6 +45,7 @@ import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
import net.sf.openrocket.arch.SystemInfo;
|
||||
import net.sf.openrocket.gui.components.CsvOptionPanel;
|
||||
import net.sf.openrocket.gui.simulation.SimulationConfigDialog;
|
||||
import net.sf.openrocket.gui.util.ColorConversion;
|
||||
import net.sf.openrocket.gui.util.FileHelper;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
@ -57,7 +58,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.logging.Warning;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
@ -72,7 +72,6 @@ import net.sf.openrocket.gui.adaptors.ColumnTableModel;
|
||||
import net.sf.openrocket.gui.adaptors.ColumnTableRowSorter;
|
||||
import net.sf.openrocket.gui.adaptors.ValueColumn;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.simulation.SimulationEditDialog;
|
||||
import net.sf.openrocket.gui.simulation.SimulationRunDialog;
|
||||
import net.sf.openrocket.gui.simulation.SimulationWarningDialog;
|
||||
import net.sf.openrocket.gui.util.Icons;
|
||||
@ -888,9 +887,11 @@ public class SimulationPanel extends JPanel {
|
||||
}
|
||||
|
||||
private void openDialog(boolean plotMode, boolean isNewSimulation, final Simulation... sims) {
|
||||
SimulationEditDialog d = new SimulationEditDialog(SwingUtilities.getWindowAncestor(this), document, isNewSimulation, sims);
|
||||
SimulationConfigDialog d = new SimulationConfigDialog(SwingUtilities.getWindowAncestor(this), document, isNewSimulation, sims);
|
||||
if (plotMode) {
|
||||
d.setPlotMode();
|
||||
d.switchToPlotTab();
|
||||
} else {
|
||||
d.switchToSettingsTab();
|
||||
}
|
||||
d.setVisible(true);
|
||||
fireMaintainSelection();
|
||||
|
@ -0,0 +1,456 @@
|
||||
package net.sf.openrocket.gui.simulation;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.document.events.DocumentChangeEvent;
|
||||
import net.sf.openrocket.gui.components.ConfigurationComboBox;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.util.UITheme;
|
||||
import net.sf.openrocket.gui.widgets.SelectColorButton;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.simulation.extension.SimulationExtension;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.startup.Preferences;
|
||||
import net.sf.openrocket.util.StateChangeListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import java.awt.Color;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventObject;
|
||||
import java.util.List;
|
||||
|
||||
public class SimulationConfigDialog extends JDialog {
|
||||
private static final long serialVersionUID = -1068127685642912715L;
|
||||
|
||||
private final Window parentWindow;
|
||||
private final Simulation[] simulationList;
|
||||
private final OpenRocketDocument document;
|
||||
private final JTabbedPane tabbedPane;
|
||||
private JButton okButton;
|
||||
private JButton cancelButton;
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final Preferences preferences = Application.getPreferences();
|
||||
|
||||
|
||||
private final WindowListener applyChangesToSimsListener;
|
||||
private final Simulation initialSim; // A copy of the first selected simulation before it was modified
|
||||
private final boolean initialIsSaved; // Whether the document was saved before the dialog was opened
|
||||
private boolean isModified = false; // Whether the simulation has been modified
|
||||
private final boolean isNewSimulation; // Whether you are editing a new simulation, or an existing one
|
||||
|
||||
private static final int SETTINGS_IDX = 0;
|
||||
private static final int PLOT_IDX = 1;
|
||||
private static final int EXPORT_IDX = 2;
|
||||
|
||||
private final SimulationPlotPanel plotTab;
|
||||
private final SimulationExportPanel exportTab;
|
||||
|
||||
private static Color multiCompEditColor;
|
||||
|
||||
static {
|
||||
initColors();
|
||||
}
|
||||
|
||||
public SimulationConfigDialog(Window parent, final OpenRocketDocument document, boolean isNewSimulation, Simulation... sims) {
|
||||
super(parent, sims.length == 1 ? trans.get("simedtdlg.title.Editsim") : trans.get("simedtdlg.title.MultiSimEdit"),
|
||||
JDialog.ModalityType.DOCUMENT_MODAL);
|
||||
this.document = document;
|
||||
this.parentWindow = parent;
|
||||
this.simulationList = sims;
|
||||
this.initialSim = simulationList[0].clone();
|
||||
this.initialIsSaved = document.isSaved();
|
||||
this.isNewSimulation = isNewSimulation;
|
||||
|
||||
simulationList[0].addChangeListener(new StateChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(EventObject e) {
|
||||
isModified = true;
|
||||
setTitle("* " + getTitle()); // Add component changed indicator to the title
|
||||
simulationList[0].removeChangeListener(this);
|
||||
}
|
||||
});
|
||||
|
||||
final JPanel contentPanel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
// ======== Top panel ========
|
||||
addTopPanel(document, contentPanel);
|
||||
|
||||
|
||||
// ======== Tabbed pane ========
|
||||
this.tabbedPane = new JTabbedPane();
|
||||
|
||||
//// Simulation Settings
|
||||
final SimulationSettingsPanel settingsTab = new SimulationSettingsPanel(document, simulationList[0]);
|
||||
tabbedPane.addTab(trans.get("simedtdlg.tab.Settings"), settingsTab);
|
||||
|
||||
//// Plot data
|
||||
this.plotTab = new SimulationPlotPanel(simulationList[0]);
|
||||
tabbedPane.addTab(trans.get("simedtdlg.tab.Plotdata"), plotTab);
|
||||
if (isMultiCompEdit()) {
|
||||
tabbedPane.setEnabledAt(PLOT_IDX, false);
|
||||
tabbedPane.setToolTipTextAt(PLOT_IDX, trans.get("SimulationConfigDialog.tab.plotDis.ttip"));
|
||||
}
|
||||
|
||||
//// Export data
|
||||
this.exportTab = new SimulationExportPanel(simulationList[0]);
|
||||
tabbedPane.addTab(trans.get("simedtdlg.tab.Exportdata"), exportTab);
|
||||
if (isMultiCompEdit()) {
|
||||
tabbedPane.setEnabledAt(EXPORT_IDX, false);
|
||||
tabbedPane.setToolTipTextAt(EXPORT_IDX, trans.get("SimulationConfigDialog.tab.expDis.ttip"));
|
||||
}
|
||||
|
||||
contentPanel.add(tabbedPane, "grow, wrap");
|
||||
|
||||
|
||||
// ======== Bottom panel ========
|
||||
addBottomPanel(contentPanel);
|
||||
|
||||
|
||||
tabbedPane.addChangeListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
if (okButton == null) {
|
||||
return;
|
||||
}
|
||||
int selectedIndex = tabbedPane.getSelectedIndex();
|
||||
switch (selectedIndex) {
|
||||
case SETTINGS_IDX:
|
||||
okButton.setText(trans.get("dlg.but.ok"));
|
||||
cancelButton.setText(trans.get("dlg.but.cancel"));
|
||||
SimulationConfigDialog.this.revalidate();
|
||||
break;
|
||||
case PLOT_IDX:
|
||||
okButton.setText(trans.get("SimulationEditDialog.btn.plot"));
|
||||
cancelButton.setText(trans.get("dlg.but.close"));
|
||||
SimulationConfigDialog.this.revalidate();
|
||||
break;
|
||||
case EXPORT_IDX:
|
||||
okButton.setText(trans.get("SimulationEditDialog.btn.export"));
|
||||
cancelButton.setText(trans.get("dlg.but.close"));
|
||||
SimulationConfigDialog.this.revalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
this.add(contentPanel);
|
||||
this.validate();
|
||||
this.pack();
|
||||
|
||||
this.setLocationByPlatform(true);
|
||||
|
||||
this.applyChangesToSimsListener = new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
copyChangesToAllSims();
|
||||
}
|
||||
};
|
||||
this.addWindowListener(applyChangesToSimsListener);
|
||||
|
||||
GUIUtil.setDisposableDialogOptions(this, null);
|
||||
}
|
||||
|
||||
private static void initColors() {
|
||||
updateColors();
|
||||
UITheme.Theme.addUIThemeChangeListener(SimulationConfigDialog::updateColors);
|
||||
}
|
||||
|
||||
private static void updateColors() {
|
||||
multiCompEditColor = GUIUtil.getUITheme().getMultiCompEditColor();
|
||||
}
|
||||
|
||||
public void switchToSettingsTab() {
|
||||
tabbedPane.setSelectedIndex(SETTINGS_IDX);
|
||||
}
|
||||
|
||||
public void switchToPlotTab() {
|
||||
tabbedPane.setSelectedIndex(PLOT_IDX);
|
||||
}
|
||||
|
||||
public void switchToExportTab() {
|
||||
tabbedPane.setSelectedIndex(EXPORT_IDX);
|
||||
}
|
||||
|
||||
private void addTopPanel(OpenRocketDocument document, JPanel contentPanel) {
|
||||
JPanel topPanel = new JPanel(new MigLayout("fill, ins 0"));
|
||||
|
||||
//// Name:
|
||||
topPanel.add(new JLabel(trans.get("simedtdlg.lbl.Simname") + " "), "growx 0, gapright para");
|
||||
final JTextField field = new JTextField(simulationList[0].getName());
|
||||
field.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
setText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
setText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
setText();
|
||||
}
|
||||
|
||||
private void setText() {
|
||||
String name = field.getText();
|
||||
if (name == null || name.equals(""))
|
||||
return;
|
||||
simulationList[0].setName(name);
|
||||
|
||||
}
|
||||
});
|
||||
topPanel.add(field, "growx, wrap");
|
||||
|
||||
//// Flight selector
|
||||
//// Flight configuration:
|
||||
JLabel label = new JLabel(trans.get("simedtdlg.lbl.Flightcfg"));
|
||||
//// Select the motor configuration to use.
|
||||
label.setToolTipText(trans.get("simedtdlg.lbl.ttip.Flightcfg"));
|
||||
topPanel.add(label, "growx 0, gapright para");
|
||||
|
||||
final Rocket rkt = document.getRocket();
|
||||
final FlightConfiguration config = rkt.getFlightConfiguration(simulationList[0].getFlightConfigurationId());
|
||||
final ConfigurationComboBox configComboBox = new ConfigurationComboBox(rkt, false);
|
||||
configComboBox.setSelectedItem(config);
|
||||
|
||||
//// Select the motor configuration to use.
|
||||
configComboBox.setToolTipText(trans.get("simedtdlg.combo.ttip.Flightcfg"));
|
||||
configComboBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
FlightConfiguration config = (FlightConfiguration)configComboBox.getSelectedItem();
|
||||
FlightConfigurationId id = config.getId();
|
||||
|
||||
simulationList[0].setFlightConfigurationId( id );
|
||||
}
|
||||
});
|
||||
topPanel.add(configComboBox, "span");
|
||||
|
||||
topPanel.add(new JPanel(), "growx, wrap");
|
||||
|
||||
contentPanel.add(topPanel, "growx, wrap");
|
||||
}
|
||||
|
||||
private void addBottomPanel(JPanel contentPanel) {
|
||||
final JPanel bottomPanel = new JPanel(new MigLayout("fill, ins 0"));
|
||||
|
||||
//// Multi-simulation edit
|
||||
if (isMultiCompEdit()) {
|
||||
StyledLabel multiSimEditLabel = new StyledLabel("", -1, StyledLabel.Style.BOLD);
|
||||
multiSimEditLabel.setFontColor(multiCompEditColor);
|
||||
multiSimEditLabel.setText(trans.get("simedtdlg.title.MultiSimEdit"));
|
||||
StringBuilder components = new StringBuilder(trans.get("simedtdlg.title.MultiSimEdit.ttip"));
|
||||
for (int i = 0; i < simulationList.length; i++) {
|
||||
if (i < simulationList.length - 1) {
|
||||
components.append(simulationList[i].getName()).append(", ");
|
||||
} else {
|
||||
components.append(simulationList[i].getName());
|
||||
}
|
||||
}
|
||||
multiSimEditLabel.setToolTipText(components.toString());
|
||||
bottomPanel.add(multiSimEditLabel, "align left");
|
||||
}
|
||||
|
||||
//// Run simulation button
|
||||
// TODO: disable when sim is up to date?
|
||||
/*JButton button = new SelectColorButton(trans.get("SimulationEditDialog.btn.simulateAndPlot"));
|
||||
if (!isSingleEdit()) {
|
||||
button.setText(trans.get("SimulationEditDialog.btn.simulate"));
|
||||
}
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
copyChangesToAllSims();
|
||||
SimulationRunDialog dialog = SimulationRunDialog.runSimulations(parentWindow, SimulationEditDialog.this.document, simulationList);
|
||||
if (allowsPlotMode() && dialog.isAllSimulationsSuccessful()) {
|
||||
refreshView();
|
||||
setPlotMode();
|
||||
}
|
||||
}
|
||||
});
|
||||
simEditPanel.add(button, "align right, gapright 10lp, tag ok");*/
|
||||
|
||||
//// Cancel button
|
||||
this.cancelButton = new SelectColorButton(trans.get("dlg.but.cancel"));
|
||||
this.cancelButton.setToolTipText(trans.get("SimulationEditDialog.btn.Cancel.ttip"));
|
||||
this.cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (tabbedPane.getSelectedIndex() == SETTINGS_IDX) {
|
||||
cancelSimEdit();
|
||||
} else {
|
||||
// Normal close action
|
||||
closeDialog();
|
||||
}
|
||||
|
||||
// TODO: include plot/export undo?
|
||||
}
|
||||
});
|
||||
bottomPanel.add(this.cancelButton, "split 2, tag ok");
|
||||
|
||||
//// Ok button
|
||||
this.okButton = new SelectColorButton(trans.get("dlg.but.ok"));
|
||||
this.okButton.setToolTipText(trans.get("SimulationEditDialog.btn.OK.ttip"));
|
||||
this.okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
copyChangesToAllSims();
|
||||
|
||||
// Run outdated simulations
|
||||
Simulation[] outdatedSims = getOutdatedSimulations();
|
||||
if (outdatedSims.length > 0) {
|
||||
new SimulationRunDialog(SimulationConfigDialog.this.parentWindow, document, outdatedSims).setVisible(true);
|
||||
}
|
||||
|
||||
int tabIdx = tabbedPane.getSelectedIndex();
|
||||
if (tabIdx == PLOT_IDX) {
|
||||
JDialog plot = plotTab.doPlot(SimulationConfigDialog.this.parentWindow);
|
||||
if (plot != null) {
|
||||
plot.setVisible(true);
|
||||
}
|
||||
closeDialog();
|
||||
return;
|
||||
} else if (tabIdx == EXPORT_IDX) {
|
||||
if (exportTab.doExport()) {
|
||||
closeDialog();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
closeDialog();
|
||||
}
|
||||
});
|
||||
bottomPanel.add(this.okButton, "tag ok");
|
||||
|
||||
contentPanel.add(bottomPanel, "growx, wrap");
|
||||
}
|
||||
|
||||
private void copyChangesToAllSims() {
|
||||
if (isMultiCompEdit()) {
|
||||
for (int i = 1; i < simulationList.length; i++) {
|
||||
simulationList[i].getOptions().copyConditionsFrom(simulationList[0].getOptions());
|
||||
simulationList[i].getSimulationExtensions().clear();
|
||||
for (SimulationExtension c : simulationList[0].getSimulationExtensions()) {
|
||||
simulationList[i].getSimulationExtensions().add(c.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Simulation[] getOutdatedSimulations() {
|
||||
List<Simulation> outdated = new ArrayList<>();
|
||||
for (Simulation sim : simulationList) {
|
||||
if (!Simulation.isStatusUpToDate(sim.getStatus())) {
|
||||
outdated.add(sim);
|
||||
}
|
||||
}
|
||||
return outdated.toArray(new Simulation[0]);
|
||||
}
|
||||
|
||||
private boolean isMultiCompEdit() {
|
||||
return simulationList.length > 1;
|
||||
}
|
||||
|
||||
private void closeDialog() {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SimulationConfigDialog.this.removeWindowListener(applyChangesToSimsListener);
|
||||
SimulationConfigDialog.this.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private JPanel createCancelOperationContent() {
|
||||
JPanel panel = new JPanel(new MigLayout());
|
||||
String msg = isNewSimulation ? trans.get("SimulationEditDialog.CancelOperation.msg.undoAdd") :
|
||||
trans.get("SimulationEditDialog.CancelOperation.msg.discardChanges");
|
||||
JLabel msgLabel = new JLabel(msg);
|
||||
JCheckBox dontAskAgain = new JCheckBox(trans.get("SimulationEditDialog.CancelOperation.checkbox.dontAskAgain"));
|
||||
dontAskAgain.setSelected(false);
|
||||
dontAskAgain.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
preferences.setShowDiscardSimulationConfirmation(false);
|
||||
}
|
||||
// Unselected state should be not be possible and thus not be handled
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(msgLabel, "left, wrap");
|
||||
panel.add(dontAskAgain, "left, gaptop para");
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void cancelSimEdit() {
|
||||
// Don't do anything on cancel if you are editing an existing simulation, and it is not modified
|
||||
if (!isNewSimulation && !isModified) {
|
||||
closeDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply the cancel operation if set to auto discard in preferences
|
||||
if (!preferences.isShowDiscardSimulationConfirmation()) {
|
||||
discardChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
// Yes/No dialog: Are you sure you want to discard your changes?
|
||||
JPanel msg = createCancelOperationContent();
|
||||
int resultYesNo = JOptionPane.showConfirmDialog(SimulationConfigDialog.this, msg,
|
||||
trans.get("SimulationEditDialog.CancelOperation.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||
if (resultYesNo == JOptionPane.YES_OPTION) {
|
||||
discardChanges();
|
||||
}
|
||||
}
|
||||
|
||||
private void discardChanges() {
|
||||
if (isNewSimulation) {
|
||||
document.removeSimulation(simulationList[0]);
|
||||
} else {
|
||||
undoSimulationChanges();
|
||||
}
|
||||
document.setSaved(this.initialIsSaved); // Restore the saved state of the document
|
||||
document.fireDocumentChangeEvent(new DocumentChangeEvent(this));
|
||||
|
||||
closeDialog();
|
||||
}
|
||||
|
||||
private void undoSimulationChanges() {
|
||||
if (simulationList == null || simulationList.length == 0) {
|
||||
return;
|
||||
}
|
||||
simulationList[0].loadFrom(initialSim);
|
||||
}
|
||||
}
|
@ -1,476 +0,0 @@
|
||||
package net.sf.openrocket.gui.simulation;
|
||||
|
||||
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.util.EventObject;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.document.events.DocumentChangeEvent;
|
||||
import net.sf.openrocket.gui.components.ConfigurationComboBox;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.gui.util.UITheme;
|
||||
import net.sf.openrocket.gui.widgets.SelectColorButton;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.simulation.extension.SimulationExtension;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.startup.Preferences;
|
||||
import net.sf.openrocket.util.StateChangeListener;
|
||||
|
||||
|
||||
public class SimulationEditDialog extends JDialog {
|
||||
private static final long serialVersionUID = -4468157685542912715L;
|
||||
private final Window parentWindow;
|
||||
private final Simulation[] simulationList;
|
||||
private final OpenRocketDocument document;
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final Preferences preferences = Application.getPreferences();
|
||||
|
||||
JPanel cards;
|
||||
private final static String EDITMODE = "EDIT";
|
||||
private final static String PLOTMODE = "PLOT";
|
||||
|
||||
private final WindowListener applyChangesToSimsListener;
|
||||
private final Simulation initialSim; // A copy of the first selected simulation before it was modified
|
||||
private final boolean initialIsSaved; // Whether the document was saved before the dialog was opened
|
||||
private boolean isModified = false; // Whether the simulation has been modified
|
||||
private final boolean isNewSimulation; // Whether you are editing a new simulation, or an existing one
|
||||
|
||||
private static Color multiCompEditColor;
|
||||
|
||||
static {
|
||||
initColors();
|
||||
}
|
||||
|
||||
public SimulationEditDialog(Window parent, final OpenRocketDocument document, boolean isNewSimulation, Simulation... sims) {
|
||||
//// Edit simulation
|
||||
super(parent, sims.length == 1 ? trans.get("simedtdlg.title.Editsim") : trans.get("simedtdlg.title.MultiSimEdit"),
|
||||
JDialog.ModalityType.DOCUMENT_MODAL);
|
||||
this.document = document;
|
||||
this.parentWindow = parent;
|
||||
this.simulationList = sims;
|
||||
this.initialSim = simulationList[0].clone();
|
||||
this.initialIsSaved = document.isSaved();
|
||||
this.isNewSimulation = isNewSimulation;
|
||||
|
||||
simulationList[0].addChangeListener(new StateChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(EventObject e) {
|
||||
isModified = true;
|
||||
setTitle("* " + getTitle()); // Add component changed indicator to the title
|
||||
simulationList[0].removeChangeListener(this);
|
||||
}
|
||||
});
|
||||
|
||||
this.cards = new JPanel(new CardLayout());
|
||||
this.add(cards);
|
||||
buildEditCard();
|
||||
buildPlotCard();
|
||||
|
||||
this.validate();
|
||||
this.pack();
|
||||
|
||||
this.setLocationByPlatform(true);
|
||||
|
||||
this.applyChangesToSimsListener = new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
copyChangesToAllSims();
|
||||
}
|
||||
};
|
||||
this.addWindowListener(applyChangesToSimsListener);
|
||||
|
||||
GUIUtil.setDisposableDialogOptions(this, null);
|
||||
}
|
||||
|
||||
private static void initColors() {
|
||||
updateColors();
|
||||
UITheme.Theme.addUIThemeChangeListener(SimulationEditDialog::updateColors);
|
||||
}
|
||||
|
||||
private static void updateColors() {
|
||||
multiCompEditColor = GUIUtil.getUITheme().getMultiCompEditColor();
|
||||
}
|
||||
|
||||
private boolean isSingleEdit() {
|
||||
return simulationList.length == 1;
|
||||
}
|
||||
|
||||
private boolean allowsPlotMode() {
|
||||
return simulationList.length == 1 && simulationList[0].hasSimulationData();
|
||||
}
|
||||
|
||||
public void setEditMode() {
|
||||
String baseTitle = simulationList.length == 1 ?
|
||||
trans.get("simedtdlg.title.Editsim") : trans.get("simedtdlg.title.MultiSimEdit");
|
||||
setTitle((isModified ? "* " : "") + baseTitle);
|
||||
CardLayout cl = (CardLayout) (cards.getLayout());
|
||||
cl.show(cards, EDITMODE);
|
||||
cards.validate();
|
||||
this.addWindowListener(applyChangesToSimsListener);
|
||||
}
|
||||
|
||||
public void setPlotMode() {
|
||||
if (!allowsPlotMode()) {
|
||||
return;
|
||||
}
|
||||
this.removeWindowListener(applyChangesToSimsListener);
|
||||
setTitle((isModified ? "* " : "") + trans.get("simplotpanel.title.Plotsim"));
|
||||
CardLayout cl = (CardLayout) (cards.getLayout());
|
||||
cl.show(cards, PLOTMODE);
|
||||
cards.validate();
|
||||
}
|
||||
|
||||
private void copyChangesToAllSims() {
|
||||
if (simulationList.length > 1) {
|
||||
for (int i = 1; i < simulationList.length; i++) {
|
||||
simulationList[i].getOptions().copyConditionsFrom(simulationList[0].getOptions());
|
||||
simulationList[i].getSimulationExtensions().clear();
|
||||
for (SimulationExtension c : simulationList[0].getSimulationExtensions()) {
|
||||
simulationList[i].getSimulationExtensions().add(c.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshView() {
|
||||
cards.removeAll();
|
||||
buildEditCard();
|
||||
buildPlotCard();
|
||||
this.validate();
|
||||
}
|
||||
|
||||
private void buildEditCard() {
|
||||
JPanel simEditPanel = new JPanel(new MigLayout("fill, hidemode 1"));
|
||||
|
||||
if (isSingleEdit()) {
|
||||
JPanel panel = new JPanel(new MigLayout("fill, ins 0"));
|
||||
|
||||
//// Simulation name:
|
||||
panel.add(new JLabel(trans.get("simedtdlg.lbl.Simname") + " "), "growx 0, gapright para");
|
||||
final JTextField field = new JTextField(simulationList[0].getName());
|
||||
field.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
setText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
setText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
setText();
|
||||
}
|
||||
|
||||
private void setText() {
|
||||
String name = field.getText();
|
||||
if (name == null || name.equals(""))
|
||||
return;
|
||||
simulationList[0].setName(name);
|
||||
|
||||
}
|
||||
});
|
||||
panel.add(field, "growx, wrap");
|
||||
|
||||
//// Flight selector
|
||||
//// Flight configuration:
|
||||
JLabel label = new JLabel(trans.get("simedtdlg.lbl.Flightcfg"));
|
||||
//// Select the motor configuration to use.
|
||||
label.setToolTipText(trans.get("simedtdlg.lbl.ttip.Flightcfg"));
|
||||
panel.add(label, "growx 0, gapright para");
|
||||
|
||||
final Rocket rkt = document.getRocket();
|
||||
final FlightConfiguration config = rkt.getFlightConfiguration(simulationList[0].getFlightConfigurationId());
|
||||
final ConfigurationComboBox configComboBox = new ConfigurationComboBox(rkt, false);
|
||||
configComboBox.setSelectedItem(config);
|
||||
|
||||
//// Select the motor configuration to use.
|
||||
configComboBox.setToolTipText(trans.get("simedtdlg.combo.ttip.Flightcfg"));
|
||||
configComboBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
FlightConfiguration config = (FlightConfiguration)configComboBox.getSelectedItem();
|
||||
FlightConfigurationId id = config.getId();
|
||||
|
||||
simulationList[0].setFlightConfigurationId( id );
|
||||
}
|
||||
});
|
||||
panel.add(configComboBox, "span");
|
||||
|
||||
panel.add(new JPanel(), "growx, wrap");
|
||||
|
||||
simEditPanel.add(panel, "growx, wrap");
|
||||
}
|
||||
JTabbedPane tabbedPane = new JTabbedPane();
|
||||
|
||||
//// Launch conditions
|
||||
tabbedPane.addTab(trans.get("simedtdlg.tab.Launchcond"), new SimulationConditionsPanel(simulationList[0]));
|
||||
//// Simulation options
|
||||
tabbedPane.addTab(trans.get("simedtdlg.tab.Simopt"), new SimulationOptionsPanel(document, simulationList[0]));
|
||||
|
||||
tabbedPane.setSelectedIndex(0);
|
||||
|
||||
simEditPanel.add(tabbedPane, "spanx, grow, wrap");
|
||||
|
||||
|
||||
//// Open Plot button
|
||||
JButton button = new SelectColorButton(trans.get("SimulationEditDialog.btn.plot") + " >>");
|
||||
button.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SimulationEditDialog.this.setPlotMode();
|
||||
}
|
||||
|
||||
});
|
||||
simEditPanel.add(button, "spanx, split 5, align left");
|
||||
if (allowsPlotMode()) {
|
||||
button.setVisible(true);
|
||||
} else {
|
||||
button.setVisible(false);
|
||||
}
|
||||
|
||||
//// Multi-simulation edit
|
||||
if (simulationList.length > 1) {
|
||||
StyledLabel multiSimEditLabel = new StyledLabel("", -1, StyledLabel.Style.BOLD);
|
||||
multiSimEditLabel.setFontColor(multiCompEditColor);
|
||||
multiSimEditLabel.setText(trans.get("simedtdlg.title.MultiSimEdit"));
|
||||
StringBuilder components = new StringBuilder(trans.get("simedtdlg.title.MultiSimEdit.ttip"));
|
||||
for (int i = 0; i < simulationList.length; i++) {
|
||||
if (i < simulationList.length - 1) {
|
||||
components.append(simulationList[i].getName()).append(", ");
|
||||
} else {
|
||||
components.append(simulationList[i].getName());
|
||||
}
|
||||
}
|
||||
multiSimEditLabel.setToolTipText(components.toString());
|
||||
simEditPanel.add(multiSimEditLabel, "align left");
|
||||
}
|
||||
|
||||
//// Run simulation button
|
||||
button = new SelectColorButton(trans.get("SimulationEditDialog.btn.simulateAndPlot"));
|
||||
if (!isSingleEdit()) {
|
||||
button.setText(trans.get("SimulationEditDialog.btn.simulate"));
|
||||
}
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
copyChangesToAllSims();
|
||||
SimulationRunDialog dialog = SimulationRunDialog.runSimulations(parentWindow, SimulationEditDialog.this.document, simulationList);
|
||||
if (allowsPlotMode() && dialog.isAllSimulationsSuccessful()) {
|
||||
refreshView();
|
||||
setPlotMode();
|
||||
}
|
||||
}
|
||||
});
|
||||
simEditPanel.add(button, "align right, gapright 10lp, tag ok");
|
||||
|
||||
//// Cancel button
|
||||
JButton cancelButton = new SelectColorButton(trans.get("dlg.but.cancel"));
|
||||
cancelButton.setToolTipText(trans.get("SimulationEditDialog.btn.Cancel.ttip"));
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Don't do anything on cancel if you are editing an existing simulation, and it is not modified
|
||||
if (!isNewSimulation && !isModified) {
|
||||
SimulationEditDialog.this.removeWindowListener(applyChangesToSimsListener);
|
||||
SimulationEditDialog.this.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply the cancel operation if set to auto discard in preferences
|
||||
if (!preferences.isShowDiscardSimulationConfirmation()) {
|
||||
discardChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
// Yes/No dialog: Are you sure you want to discard your changes?
|
||||
JPanel msg = createCancelOperationContent();
|
||||
int resultYesNo = JOptionPane.showConfirmDialog(SimulationEditDialog.this, msg,
|
||||
trans.get("SimulationEditDialog.CancelOperation.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||
if (resultYesNo == JOptionPane.YES_OPTION) {
|
||||
discardChanges();
|
||||
}
|
||||
}
|
||||
});
|
||||
simEditPanel.add(cancelButton, "tag ok");
|
||||
|
||||
//// Ok button
|
||||
JButton okButton = new SelectColorButton(trans.get("dlg.but.ok"));
|
||||
okButton.setToolTipText(trans.get("SimulationEditDialog.btn.OK.ttip"));
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
copyChangesToAllSims();
|
||||
SimulationEditDialog.this.dispose();
|
||||
}
|
||||
});
|
||||
simEditPanel.add(okButton, "tag ok");
|
||||
|
||||
cards.add(simEditPanel, EDITMODE);
|
||||
}
|
||||
|
||||
private void buildPlotCard() {
|
||||
if (allowsPlotMode()) {
|
||||
JPanel plotExportPanel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
//// Simulation name:
|
||||
plotExportPanel.add(new JLabel(trans.get("simedtdlg.lbl.Simname") + " "), "span, split 2, shrink");
|
||||
final JTextField field = new JTextField(simulationList[0].getName());
|
||||
field.setEditable(false);
|
||||
plotExportPanel.add(field, "shrinky, growx, wrap");
|
||||
|
||||
final JTabbedPane tabbedPane = new JTabbedPane();
|
||||
|
||||
//// Plot data
|
||||
final SimulationPlotPanel plotTab = new SimulationPlotPanel(simulationList[0]);
|
||||
tabbedPane.addTab(trans.get("simedtdlg.tab.Plotdata"), plotTab);
|
||||
//// Export data
|
||||
final SimulationExportPanel exportTab = new SimulationExportPanel(simulationList[0]);
|
||||
tabbedPane.addTab(trans.get("simedtdlg.tab.Exportdata"), exportTab);
|
||||
|
||||
plotExportPanel.add(tabbedPane, "grow, wrap");
|
||||
|
||||
JButton button = new SelectColorButton("<< " + trans.get("SimulationEditDialog.btn.edit"));
|
||||
button.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SimulationEditDialog.this.setEditMode();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
plotExportPanel.add(button, "spanx, split 3, align left");
|
||||
|
||||
final JButton ok = new SelectColorButton(trans.get("SimulationEditDialog.btn.plot"));
|
||||
|
||||
tabbedPane.addChangeListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
int selectedIndex = tabbedPane.getSelectedIndex();
|
||||
switch (selectedIndex) {
|
||||
case 0:
|
||||
ok.setText(trans.get("SimulationEditDialog.btn.plot"));
|
||||
plotExportPanel.revalidate();
|
||||
break;
|
||||
case 1:
|
||||
ok.setText(trans.get("SimulationEditDialog.btn.export"));
|
||||
plotExportPanel.revalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
ok.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// If the simulation is out of date, run the simulation.
|
||||
if (!Simulation.isStatusUpToDate(simulationList[0].getStatus())) {
|
||||
new SimulationRunDialog(SimulationEditDialog.this.parentWindow, document, simulationList[0]).setVisible(true);
|
||||
}
|
||||
|
||||
if (tabbedPane.getSelectedIndex() == 0) {
|
||||
JDialog plot = plotTab.doPlot(SimulationEditDialog.this.parentWindow);
|
||||
if (plot != null) {
|
||||
plot.setVisible(true);
|
||||
}
|
||||
} else {
|
||||
if (exportTab.doExport()) {
|
||||
SimulationEditDialog.this.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
plotExportPanel.add(ok, "tag ok, split 2");
|
||||
|
||||
//// Close button
|
||||
JButton close = new SelectColorButton(trans.get("dlg.but.close"));
|
||||
close.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SimulationEditDialog.this.dispose();
|
||||
}
|
||||
});
|
||||
plotExportPanel.add(close, "tag cancel");
|
||||
//plotExportPanel.validate();
|
||||
cards.add(plotExportPanel, PLOTMODE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private JPanel createCancelOperationContent() {
|
||||
JPanel panel = new JPanel(new MigLayout());
|
||||
String msg = isNewSimulation ? trans.get("SimulationEditDialog.CancelOperation.msg.undoAdd") :
|
||||
trans.get("SimulationEditDialog.CancelOperation.msg.discardChanges");
|
||||
JLabel msgLabel = new JLabel(msg);
|
||||
JCheckBox dontAskAgain = new JCheckBox(trans.get("SimulationEditDialog.CancelOperation.checkbox.dontAskAgain"));
|
||||
dontAskAgain.setSelected(false);
|
||||
dontAskAgain.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
preferences.setShowDiscardSimulationConfirmation(false);
|
||||
}
|
||||
// Unselected state should be not be possible and thus not be handled
|
||||
}
|
||||
});
|
||||
|
||||
panel.add(msgLabel, "left, wrap");
|
||||
panel.add(dontAskAgain, "left, gaptop para");
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void discardChanges() {
|
||||
if (isNewSimulation) {
|
||||
document.removeSimulation(simulationList[0]);
|
||||
} else {
|
||||
undoSimulationChanges();
|
||||
}
|
||||
document.setSaved(this.initialIsSaved); // Restore the saved state of the document
|
||||
document.fireDocumentChangeEvent(new DocumentChangeEvent(this));
|
||||
|
||||
SimulationEditDialog.this.removeWindowListener(applyChangesToSimsListener);
|
||||
SimulationEditDialog.this.dispose();
|
||||
}
|
||||
|
||||
private void undoSimulationChanges() {
|
||||
if (simulationList == null || simulationList.length == 0) {
|
||||
return;
|
||||
}
|
||||
simulationList[0].loadFrom(initialSim);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.io.Serial;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
|
||||
@ -51,6 +52,7 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class SimulationPlotPanel extends JPanel {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -2227129713185477998L;
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
@ -0,0 +1,36 @@
|
||||
package net.sf.openrocket.gui.simulation;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import java.io.Serial;
|
||||
|
||||
public class SimulationSettingsPanel extends JPanel {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -2114129713185477998L;
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
public SimulationSettingsPanel(final OpenRocketDocument document, final Simulation simulation) {
|
||||
super(new MigLayout("fill"));
|
||||
|
||||
JTabbedPane tabbedPane = new JTabbedPane();
|
||||
|
||||
//// Launch conditions
|
||||
tabbedPane.addTab(trans.get("simedtdlg.tab.Launchcond"), new SimulationConditionsPanel(simulation));
|
||||
|
||||
//// Simulation options
|
||||
tabbedPane.addTab(trans.get("simedtdlg.tab.Simopt"), new SimulationOptionsPanel(document, simulation));
|
||||
|
||||
tabbedPane.setSelectedIndex(0);
|
||||
|
||||
this.add(tabbedPane, "spanx, grow, wrap");
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user