X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fnet%2Fsf%2Fopenrocket%2Fgui%2Fmain%2FSimulationPanel.java;h=36b5a608d116e47d203b6b7011dfbfa0c65c1b4c;hb=4e02be8874f0e95fe048222e7f174ef84272f795;hp=bb3cd3aa566cfad44ac2846fceef91b59f1becb8;hpb=720d4935bc6bec453e6478ad5227356c626610a2;p=debian%2Fopenrocket diff --git a/src/net/sf/openrocket/gui/main/SimulationPanel.java b/src/net/sf/openrocket/gui/main/SimulationPanel.java index bb3cd3aa..36b5a608 100644 --- a/src/net/sf/openrocket/gui/main/SimulationPanel.java +++ b/src/net/sf/openrocket/gui/main/SimulationPanel.java @@ -5,6 +5,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Arrays; @@ -17,6 +18,8 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; +import javax.swing.KeyStroke; +import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.table.DefaultTableCellRenderer; @@ -25,28 +28,35 @@ import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; -import net.sf.openrocket.gui.ResizeLabel; +import net.sf.openrocket.document.events.DocumentChangeEvent; +import net.sf.openrocket.document.events.DocumentChangeListener; +import net.sf.openrocket.document.events.SimulationChangeEvent; import net.sf.openrocket.gui.adaptors.Column; import net.sf.openrocket.gui.adaptors.ColumnTableModel; +import net.sf.openrocket.gui.components.StyledLabel; +import net.sf.openrocket.gui.util.Icons; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; import net.sf.openrocket.rocketcomponent.ComponentChangeListener; import net.sf.openrocket.simulation.FlightData; +import net.sf.openrocket.startup.Application; import net.sf.openrocket.unit.UnitGroup; -import net.sf.openrocket.util.Icons; import net.sf.openrocket.util.Prefs; public class SimulationPanel extends JPanel { + private static final LogHelper log = Application.getLogger(); + private static final Translator trans = Application.getTranslator(); + private static final Color WARNING_COLOR = Color.RED; - private static final String WARNING_TEXT = "\uFF01"; // Fullwidth exclamation mark + private static final String WARNING_TEXT = "\uFF01"; // Fullwidth exclamation mark - private static final Color OK_COLOR = new Color(60,150,0); - private static final String OK_TEXT = "\u2714"; // Heavy check mark + private static final Color OK_COLOR = new Color(60, 150, 0); + private static final String OK_TEXT = "\u2714"; // Heavy check mark - private static final String NAME_PREFIX = "Simulation "; - - + private final OpenRocketDocument document; private final ColumnTableModel simulationTableModel; @@ -54,37 +64,26 @@ public class SimulationPanel extends JPanel { public SimulationPanel(OpenRocketDocument doc) { - super(new MigLayout("fill","[grow][][][][][][grow]")); + super(new MigLayout("fill", "[grow][][][][][][grow]")); JButton button; this.document = doc; - - + + //////// The simulation action buttons - button = new JButton("New simulation"); - button.setToolTipText("Add a new simulation"); + //// New simulation button + button = new JButton(trans.get("simpanel.but.newsimulation")); + //// Add a new simulation + button.setToolTipText(trans.get("simpanel.but.ttip.newsimulation")); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - - // Generate unique name for the simulation - int maxValue = 0; - for (Simulation s: document.getSimulations()) { - String name = s.getName(); - if (name.startsWith(NAME_PREFIX)) { - try { - maxValue = Math.max(maxValue, - Integer.parseInt(name.substring(NAME_PREFIX.length()))); - } catch (NumberFormatException ignore) { } - } - } - Simulation sim = new Simulation(document.getRocket()); - sim.setName(NAME_PREFIX + (maxValue+1)); + sim.setName(document.getNextSimulationName()); int n = document.getSimulationCount(); document.addSimulation(sim); @@ -93,19 +92,21 @@ public class SimulationPanel extends JPanel { simulationTable.addRowSelectionInterval(n, n); openDialog(sim, SimulationEditDialog.EDIT); - } + } }); - this.add(button,"skip 1, gapright para"); + this.add(button, "skip 1, gapright para"); - button = new JButton("Edit simulation"); - button.setToolTipText("Edit the selected simulation"); + //// Edit simulation button + button = new JButton(trans.get("simpanel.but.editsimulation")); + //// Edit the selected simulation + button.setToolTipText(trans.get("simpanel.but.ttip.editsim")); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int selected = simulationTable.getSelectedRow(); if (selected < 0) - return; // TODO: MEDIUM: "None selected" dialog - + return; // TODO: MEDIUM: "None selected" dialog + selected = simulationTable.convertRowIndexToModel(selected); simulationTable.clearSelection(); simulationTable.addRowSelectionInterval(selected, selected); @@ -113,91 +114,99 @@ public class SimulationPanel extends JPanel { openDialog(document.getSimulations().get(selected), SimulationEditDialog.EDIT); } }); - this.add(button,"gapright para"); + this.add(button, "gapright para"); - button = new JButton("Run simulations"); - button.setToolTipText("Re-run the selected simulations"); + //// Run simulations + button = new JButton(trans.get("simpanel.but.runsimulations")); + //// Re-run the selected simulations + button.setToolTipText(trans.get("simpanel.but.ttip.runsimu")); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - int[] selection = simulationTable.getSelectedRows(); - if (selection.length == 0) - return; // TODO: LOW: "None selected" dialog - - Simulation[] sims = new Simulation[selection.length]; - for (int i=0; i < selection.length; i++) { - selection[i] = simulationTable.convertRowIndexToModel(selection[i]); - sims[i] = document.getSimulation(selection[i]); - } - - long t = System.currentTimeMillis(); - new SimulationRunDialog(SwingUtilities.getWindowAncestor( - SimulationPanel.this), sims).setVisible(true); - System.err.println("Running took "+(System.currentTimeMillis()-t) + " ms"); - fireMaintainSelection(); + int[] selection = simulationTable.getSelectedRows(); + if (selection.length == 0) + return; // TODO: LOW: "None selected" dialog + + Simulation[] sims = new Simulation[selection.length]; + for (int i = 0; i < selection.length; i++) { + selection[i] = simulationTable.convertRowIndexToModel(selection[i]); + sims[i] = document.getSimulation(selection[i]); + } + + long t = System.currentTimeMillis(); + new SimulationRunDialog(SwingUtilities.getWindowAncestor( + SimulationPanel.this), sims).setVisible(true); + log.info("Running simulations took " + (System.currentTimeMillis() - t) + " ms"); + fireMaintainSelection(); } }); - this.add(button,"gapright para"); + this.add(button, "gapright para"); - button = new JButton("Delete simulations"); - button.setToolTipText("Delete the selected simulations"); + //// Delete simulations button + button = new JButton(trans.get("simpanel.but.deletesimulations")); + //// Delete the selected simulations + button.setToolTipText(trans.get("simpanel.but.ttip.deletesim")); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - int[] selection = simulationTable.getSelectedRows(); - if (selection.length == 0) - return; // TODO: LOW: "None selected" dialog - - // Verify deletion - boolean verify = Prefs.NODE.getBoolean(Prefs.CONFIRM_DELETE_SIMULATION, true); - if (verify) { - - JPanel panel = new JPanel(new MigLayout()); - JCheckBox dontAsk = new JCheckBox("Do not ask me again"); - panel.add(dontAsk,"wrap"); - panel.add(new ResizeLabel("You can change the default operation in the " + - "preferences.",-2)); - - int ret = JOptionPane.showConfirmDialog(SimulationPanel.this, - new Object[] { - "Delete the selected simulations?", - "This operation cannot be undone.", - "", - panel }, - "Delete simulations", - JOptionPane.OK_CANCEL_OPTION, - JOptionPane.WARNING_MESSAGE); - if (ret != JOptionPane.OK_OPTION) - return; - - if (dontAsk.isSelected()) { - Prefs.NODE.putBoolean(Prefs.CONFIRM_DELETE_SIMULATION, false); - } - } - - // Delete simulations - for (int i=0; i < selection.length; i++) { - selection[i] = simulationTable.convertRowIndexToModel(selection[i]); - } - Arrays.sort(selection); - for (int i=selection.length-1; i>=0; i--) { - document.removeSimulation(selection[i]); - } - simulationTableModel.fireTableDataChanged(); + int[] selection = simulationTable.getSelectedRows(); + if (selection.length == 0) + return; // TODO: LOW: "None selected" dialog + + // Verify deletion + boolean verify = Prefs.NODE.getBoolean(Prefs.CONFIRM_DELETE_SIMULATION, true); + if (verify) { + + JPanel panel = new JPanel(new MigLayout()); + //// Do not ask me again + JCheckBox dontAsk = new JCheckBox(trans.get("simpanel.checkbox.donotask")); + panel.add(dontAsk, "wrap"); + //// You can change the default operation in the preferences. + panel.add(new StyledLabel(trans.get("simpanel.lbl.defpref"), -2)); + + int ret = JOptionPane.showConfirmDialog(SimulationPanel.this, + new Object[] { + //// Delete the selected simulations? + trans.get("simpanel.dlg.lbl.DeleteSim1"), + //// This operation cannot be undone. + trans.get("simpanel.dlg.lbl.DeleteSim2"), + "", + panel }, + //// Delete simulations + trans.get("simpanel.dlg.lbl.DeleteSim3"), + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.WARNING_MESSAGE); + if (ret != JOptionPane.OK_OPTION) + return; + + if (dontAsk.isSelected()) { + Prefs.NODE.putBoolean(Prefs.CONFIRM_DELETE_SIMULATION, false); + } + } + + // Delete simulations + for (int i = 0; i < selection.length; i++) { + selection[i] = simulationTable.convertRowIndexToModel(selection[i]); + } + Arrays.sort(selection); + for (int i = selection.length - 1; i >= 0; i--) { + document.removeSimulation(selection[i]); + } + simulationTableModel.fireTableDataChanged(); } }); - this.add(button,"gapright para"); + this.add(button, "gapright para"); - -// button = new JButton("Plot / export"); - button = new JButton("Plot flight"); + //// Plot / export button + button = new JButton(trans.get("simpanel.but.plotexport")); + // button = new JButton("Plot flight"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int selected = simulationTable.getSelectedRow(); if (selected < 0) - return; // TODO: MEDIUM: "None selected" dialog - + return; // TODO: MEDIUM: "None selected" dialog + selected = simulationTable.convertRowIndexToModel(selected); simulationTable.clearSelection(); simulationTable.addRowSelectionInterval(selected, selected); @@ -206,27 +215,28 @@ public class SimulationPanel extends JPanel { } }); this.add(button, "wrap para"); - - - + + + //////// The simulation table simulationTableModel = new ColumnTableModel( - - //// Status and warning column + + //// Status and warning column new Column("") { private JLabel label = null; - @Override + + @Override public Object getValueAt(int row) { if (row < 0 || row >= document.getSimulationCount()) return null; // Initialize the label if (label == null) { - label = new ResizeLabel(2f); + label = new StyledLabel(2f); label.setIconTextGap(1); -// label.setFont(label.getFont().deriveFont(Font.BOLD)); + // label.setFont(label.getFont().deriveFont(Font.BOLD)); } // Set simulation status icon @@ -236,7 +246,7 @@ public class SimulationPanel extends JPanel { // Set warning marker if (status == Simulation.Status.NOT_SIMULATED || - status == Simulation.Status.EXTERNAL) { + status == Simulation.Status.EXTERNAL) { label.setText(""); @@ -253,134 +263,150 @@ public class SimulationPanel extends JPanel { label.setText(WARNING_TEXT); } } - + return label; } - @Override public int getExactWidth() { - return 32; + + @Override + public int getExactWidth() { + return 36; } - @Override public Class getColumnClass() { + + @Override + public Class getColumnClass() { return JLabel.class; } }, //// Simulation name - new Column("Name") { - @Override public Object getValueAt(int row) { + //// Name + new Column(trans.get("simpanel.col.Name")) { + @Override + public Object getValueAt(int row) { if (row < 0 || row >= document.getSimulationCount()) return null; return document.getSimulation(row).getName(); } + @Override public int getDefaultWidth() { return 125; } }, - + //// Simulation motors - new Column("Motors") { - @Override public Object getValueAt(int row) { + //// Motors + new Column(trans.get("simpanel.col.Motors")) { + @Override + public Object getValueAt(int row) { if (row < 0 || row >= document.getSimulationCount()) return null; return document.getSimulation(row).getConfiguration() - .getMotorConfigurationDescription(); + .getMotorConfigurationDescription(); } + @Override public int getDefaultWidth() { return 125; } }, - + //// Apogee - new Column("Apogee") { - @Override public Object getValueAt(int row) { + new Column(trans.get("simpanel.col.Apogee")) { + @Override + public Object getValueAt(int row) { if (row < 0 || row >= document.getSimulationCount()) return null; FlightData data = document.getSimulation(row).getSimulatedData(); - if (data==null) + if (data == null) return null; return UnitGroup.UNITS_DISTANCE.getDefaultUnit().toStringUnit( data.getMaxAltitude()); } }, - + //// Maximum velocity - new Column("Max. velocity") { - @Override public Object getValueAt(int row) { + new Column(trans.get("simpanel.col.Maxvelocity")) { + @Override + public Object getValueAt(int row) { if (row < 0 || row >= document.getSimulationCount()) return null; FlightData data = document.getSimulation(row).getSimulatedData(); - if (data==null) + if (data == null) return null; return UnitGroup.UNITS_VELOCITY.getDefaultUnit().toStringUnit( data.getMaxVelocity()); } }, - + //// Maximum acceleration - new Column("Max. acceleration") { - @Override public Object getValueAt(int row) { + new Column(trans.get("simpanel.col.Maxacceleration")) { + @Override + public Object getValueAt(int row) { if (row < 0 || row >= document.getSimulationCount()) return null; FlightData data = document.getSimulation(row).getSimulatedData(); - if (data==null) + if (data == null) return null; return UnitGroup.UNITS_ACCELERATION.getDefaultUnit().toStringUnit( data.getMaxAcceleration()); } }, - + //// Time to apogee - new Column("Time to apogee") { - @Override public Object getValueAt(int row) { + new Column(trans.get("simpanel.col.Timetoapogee")) { + @Override + public Object getValueAt(int row) { if (row < 0 || row >= document.getSimulationCount()) return null; FlightData data = document.getSimulation(row).getSimulatedData(); - if (data==null) + if (data == null) return null; return UnitGroup.UNITS_FLIGHT_TIME.getDefaultUnit().toStringUnit( data.getTimeToApogee()); } }, - + //// Flight time - new Column("Flight time") { - @Override public Object getValueAt(int row) { + new Column(trans.get("simpanel.col.Flighttime")) { + @Override + public Object getValueAt(int row) { if (row < 0 || row >= document.getSimulationCount()) return null; FlightData data = document.getSimulation(row).getSimulatedData(); - if (data==null) + if (data == null) return null; return UnitGroup.UNITS_FLIGHT_TIME.getDefaultUnit().toStringUnit( data.getFlightTime()); } }, - + //// Ground hit velocity - new Column("Ground hit velocity") { - @Override public Object getValueAt(int row) { + new Column(trans.get("simpanel.col.Groundhitvelocity")) { + @Override + public Object getValueAt(int row) { if (row < 0 || row >= document.getSimulationCount()) return null; FlightData data = document.getSimulation(row).getSimulatedData(); - if (data==null) + if (data == null) return null; return UnitGroup.UNITS_VELOCITY.getDefaultUnit().toStringUnit( data.getGroundHitVelocity()); } } - + ) { @Override public int getRowCount() { @@ -388,10 +414,21 @@ public class SimulationPanel extends JPanel { } }; - simulationTable = new JTable(simulationTableModel); + // Override processKeyBinding so that the JTable does not catch + // key bindings used in menu accelerators + simulationTable = new JTable(simulationTableModel) { + @Override + protected boolean processKeyBinding(KeyStroke ks, + KeyEvent e, + int condition, + boolean pressed) { + return false; + } + }; simulationTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); simulationTable.setDefaultRenderer(Object.class, new JLabelRenderer()); simulationTableModel.setColumnWidths(simulationTable.getColumnModel()); + // Mouse listener to act on double-clicks simulationTable.addMouseListener(new MouseAdapter() { @@ -406,15 +443,24 @@ public class SimulationPanel extends JPanel { simulationTable.clearSelection(); simulationTable.addRowSelectionInterval(selected, selected); - openDialog(document.getSimulations().get(selected), + openDialog(document.getSimulations().get(selected), SimulationEditDialog.DEFAULT); } } }); - - + document.addDocumentChangeListener(new DocumentChangeListener() { + @Override + public void documentChanged(DocumentChangeEvent event) { + if (!(event instanceof SimulationChangeEvent)) + return; + simulationTableModel.fireTableDataChanged(); + } + }); + + + // Fire table change event when the rocket changes document.getRocket().addComponentChangeListener(new ComponentChangeListener() { @Override @@ -423,43 +469,49 @@ public class SimulationPanel extends JPanel { } }); - + JScrollPane scrollpane = new JScrollPane(simulationTable); - this.add(scrollpane,"spanx, grow, wrap rel"); - + this.add(scrollpane, "spanx, grow, wrap rel"); + } + public ListSelectionModel getSimulationListSelectionModel() { + return simulationTable.getSelectionModel(); + } + private void openDialog(final Simulation sim, int position) { new SimulationEditDialog(SwingUtilities.getWindowAncestor(this), sim, position) - .setVisible(true); + .setVisible(true); fireMaintainSelection(); } private void fireMaintainSelection() { - int[] selection = simulationTable.getSelectedRows(); - simulationTableModel.fireTableDataChanged(); - for (int row: selection) { - simulationTable.addRowSelectionInterval(row, row); - } + int[] selection = simulationTable.getSelectedRows(); + simulationTableModel.fireTableDataChanged(); + for (int row : selection) { + if (row >= simulationTableModel.getRowCount()) + break; + simulationTable.addRowSelectionInterval(row, row); + } } private class JLabelRenderer extends DefaultTableCellRenderer { - + @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - + if (row < 0 || row >= document.getSimulationCount()) - return super.getTableCellRendererComponent(table, value, + return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // A JLabel is self-contained and has set its own tool tip if (value instanceof JLabel) { - JLabel label = (JLabel)value; + JLabel label = (JLabel) value; if (isSelected) label.setBackground(table.getSelectionBackground()); else @@ -470,11 +522,11 @@ public class SimulationPanel extends JPanel { return label; } - Component component = super.getTableCellRendererComponent(table, value, + Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (component instanceof JComponent) { - ((JComponent)component).setToolTipText(getSimulationToolTip( + ((JComponent) component).setToolTipText(getSimulationToolTip( document.getSimulation(row))); } return component; @@ -487,18 +539,20 @@ public class SimulationPanel extends JPanel { tip = "" + sim.getName() + "
"; switch (sim.getStatus()) { case UPTODATE: + //// Up to date
tip += "Up to date
"; break; - + case LOADED: + //// Data loaded from a file
tip += "Data loaded from a file
"; break; - + case OUTDATED: tip += "Data is out of date
"; tip += "Click Run simulations to simulate.
"; break; - + case EXTERNAL: tip += "Imported data
"; return tip; @@ -521,10 +575,10 @@ public class SimulationPanel extends JPanel { } tip += "Warnings:"; - for (Warning w: warnings) { + for (Warning w : warnings) { tip += "
" + w.toString(); } - + return tip; }