diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index 6f76a838d..e5e31ce87 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -418,18 +418,18 @@ public class BasicFrame extends JFrame { button = new SelectColorButton(actions.getMoveDownAction()); panel.add(button, "sizegroup buttons, aligny 0%"); - button = new SelectColorButton(actions.getEditAction()); - button.setIcon(null); + button = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(button, actions.getEditAction()); button.setMnemonic(0); panel.add(button, "sizegroup buttons, gaptop 20%"); - button = new SelectColorButton(actions.getDuplicateAction()); - button.setIcon(null); + button = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(button, actions.getDuplicateAction()); button.setMnemonic(0); panel.add(button, "sizegroup buttons"); - button = new SelectColorButton(actions.getDeleteAction()); - button.setIcon(null); + button = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(button, actions.getDeleteAction()); button.setMnemonic(0); panel.add(button, "sizegroup buttons"); diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index 86a3ea6bf..15ed1d597 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -12,6 +12,7 @@ import java.util.List; import javax.swing.AbstractAction; import javax.swing.Action; +import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -189,6 +190,35 @@ public class RocketActions { return moveDownAction; } + /** + * Tie an action to a JButton, without using the icon or text of the action for the button. + * + * For any smartass that wants to know why you don't just initialize the JButton with the action and then set the + * icon to null and set the button text: this causes a bug where the text of the icon becomes much smaller than is intended. + * + * @param button button to tie the action to + * @param action action to tie to the button + * @param text text to display on the button + */ + public static void tieActionToButtonNoIcon(JButton button, Action action, String text) { + button.setAction(action); + button.setIcon(null); + button.setText(text); + } + + /** + * Tie an action to a JButton, without using the icon of the action for the button. + * + * For any smartass that wants to know why you don't just initialize the JButton with the action and then set the + * icon to null: this causes a bug where the text of the icon becomes much smaller than is intended. + * + * @param button button to tie the action to + * @param action action to tie to the button + */ + public static void tieActionToButtonNoIcon(JButton button, Action action) { + button.setAction(action); + button.setIcon(null); + } //////// Helper methods for the actions diff --git a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java index f8ac84ec5..efd353b90 100644 --- a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java @@ -10,7 +10,6 @@ import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; 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; @@ -98,365 +97,81 @@ public class SimulationPanel extends JPanel { private final JButton plotButton; private final JPopupMenu pm; + private final SimulationAction editSimulationAction; + private final SimulationAction runSimulationAction; + private final SimulationAction plotSimulationAction; + private final SimulationAction duplicateSimulationAction; + private final SimulationAction deleteSimulationAction; + public SimulationPanel(OpenRocketDocument doc) { super(new MigLayout("fill", "[grow][][][][][][grow]")); this.document = doc; + // Simulation actions + SimulationAction newSimulationAction = new NewSimulationAction(); + editSimulationAction = new EditSimulationAction(); + runSimulationAction = new RunSimulationAction(); + plotSimulationAction = new PlotSimulationAction(); + duplicateSimulationAction = new DuplicateSimulationAction(); + deleteSimulationAction = new DeleteSimulationAction(); - //////// The simulation action buttons + //////// The simulation action buttons //////// //// New simulation button - { - JButton button = new SelectColorButton(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) { - Simulation sim = new Simulation(document.getRocket()); - sim.setName(document.getNextSimulationName()); - - int n = document.getSimulationCount(); - document.addSimulation(sim); - simulationTableModel.fireTableDataChanged(); - simulationTable.clearSelection(); - simulationTable.addRowSelectionInterval(n, n); - - openDialog(false, sim); - } - }); - this.add(button, "skip 1, gapright para"); - } + JButton newButton = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(newButton, newSimulationAction, trans.get("simpanel.but.newsimulation")); + newButton.setToolTipText(trans.get("simpanel.but.ttip.newsimulation")); + this.add(newButton, "skip 1, gapright para"); //// Edit simulation button - editButton = new SelectColorButton(trans.get("simpanel.but.editsimulation")); - //// Edit the selected simulation + editButton = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(editButton, editSimulationAction, trans.get("simpanel.but.editsimulation")); editButton.setToolTipText(trans.get("simpanel.but.ttip.editsim")); - editButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - editSimulation(); - } - }); this.add(editButton, "gapright para"); //// Run simulations - runButton = new SelectColorButton(trans.get("simpanel.but.runsimulations")); - //// Re-run the selected simulations + runButton = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(runButton, runSimulationAction, trans.get("simpanel.but.runsimulations")); runButton.setToolTipText(trans.get("simpanel.but.ttip.runsimu")); - runButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - runSimulation(); - } - }); this.add(runButton, "gapright para"); //// Delete simulations button - deleteButton = new SelectColorButton(trans.get("simpanel.but.deletesimulations")); - //// Delete the selected simulations + deleteButton = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(deleteButton, deleteSimulationAction, trans.get("simpanel.but.deletesimulations")); deleteButton.setToolTipText(trans.get("simpanel.but.ttip.deletesim")); - deleteButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - deleteSimulation(); - } - }); this.add(deleteButton, "gapright para"); //// Plot / export button - plotButton = new SelectColorButton(trans.get("simpanel.but.plotexport")); - // button = new SelectColorButton("Plot flight"); - plotButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - plotSimulation(); - } - }); + plotButton = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(plotButton, plotSimulationAction, trans.get("simpanel.but.plotexport")); this.add(plotButton, "wrap para"); //////// The simulation table - - simulationTableModel = new ColumnTableModel( - - //// Status and warning column - new Column("") { - private JLabel label = null; - - @Override - public Object getValueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - // Initialize the label - if (label == null) { - label = new StyledLabel(2f); - label.setIconTextGap(1); - // label.setFont(label.getFont().deriveFont(Font.BOLD)); - } - - // Set simulation status icon - Simulation.Status status = document.getSimulation(row).getStatus(); - label.setIcon(Icons.SIMULATION_STATUS_ICON_MAP.get(status)); - - - // Set warning marker - if (status == Simulation.Status.NOT_SIMULATED || - status == Simulation.Status.EXTERNAL) { - - label.setText(""); - - } else { - - WarningSet w = document.getSimulation(row).getSimulatedWarnings(); - if (w == null) { - label.setText(""); - } else if (w.isEmpty()) { - label.setForeground(OK_COLOR); - label.setText(OK_TEXT); - } else { - label.setForeground(WARNING_COLOR); - label.setText(WARNING_TEXT); - } - } - - return label; - } - - @Override - public int getExactWidth() { - return 36; - } - - @Override - public Class getColumnClass() { - return JLabel.class; - } - }, - - //// Simulation name - //// 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; - } - - @Override - public Comparator getComparator() { - return new AlphanumComparator(); - } - }, - - //// Simulation configuration - new Column(trans.get("simpanel.col.Configuration")) { - @Override - public Object getValueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()){ - return null; - } - - Rocket rkt = document.getRocket(); - FlightConfigurationId fcid = document.getSimulation(row).getId(); - return descriptor.format( rkt, fcid); - } - - @Override - public int getDefaultWidth() { - return 125; - } - }, - - //// Launch rod velocity - new ValueColumn(trans.get("simpanel.col.Velocityoffrod"), UnitGroup.UNITS_VELOCITY) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getLaunchRodVelocity(); - } - - }, - - //// Apogee - new ValueColumn(trans.get("simpanel.col.Apogee"), UnitGroup.UNITS_DISTANCE) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getMaxAltitude(); - } - }, - - //// Velocity at deployment - new ValueColumn(trans.get("simpanel.col.Velocityatdeploy"), UnitGroup.UNITS_VELOCITY) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getDeploymentVelocity(); - } - }, - - //// Deployment Time from Apogee - new ValueColumn(trans.get("simpanel.col.OptimumCoastTime"), - trans.get("simpanel.col.OptimumCoastTime.ttip"), - UnitGroup.UNITS_SHORT_TIME) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null || data.getBranchCount() == 0) - return null; - - double val = data.getBranch(0).getOptimumDelay(); - if ( Double.isNaN(val) ) { - return null; - } - return val; - } - }, - - //// Maximum velocity - new ValueColumn(trans.get("simpanel.col.Maxvelocity"), UnitGroup.UNITS_VELOCITY) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getMaxVelocity(); - } - }, - - //// Maximum acceleration - new ValueColumn(trans.get("simpanel.col.Maxacceleration"), UnitGroup.UNITS_ACCELERATION) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getMaxAcceleration(); - } - }, - - //// Time to apogee - new ValueColumn(trans.get("simpanel.col.Timetoapogee"), UnitGroup.UNITS_FLIGHT_TIME) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getTimeToApogee(); - } - }, - - //// Flight time - new ValueColumn(trans.get("simpanel.col.Flighttime"), UnitGroup.UNITS_FLIGHT_TIME) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getFlightTime(); - } - }, - - //// Ground hit velocity - new ValueColumn(trans.get("simpanel.col.Groundhitvelocity"), UnitGroup.UNITS_VELOCITY) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getGroundHitVelocity(); - } - } - - ) { - - private static final long serialVersionUID = 8686456963492628476L; - - @Override - public int getRowCount() { - return document.getSimulationCount(); - } - }; + simulationTableModel = new SimulationTableModel(); // Override processKeyBinding so that the JTable does not catch // key bindings used in menu accelerators simulationTable = new ColumnTable(simulationTableModel) { - private static final long serialVersionUID = -5799340181229735630L; - - @Override - protected boolean processKeyBinding(KeyStroke ks, - KeyEvent e, - int condition, - boolean pressed) { - return false; - } }; ColumnTableRowSorter simulationTableSorter = new ColumnTableRowSorter(simulationTableModel); simulationTable.setRowSorter(simulationTableSorter); simulationTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); simulationTable.setDefaultRenderer(Object.class, new JLabelRenderer()); simulationTableModel.setColumnWidths(simulationTable.getColumnModel()); - - pm = new JPopupMenu(); - pm.add(new EditSimulationAction()); - pm.add(new DuplicateSimulationAction()); - pm.add(new DeleteSimulationAction()); - pm.addSeparator(); - pm.add(new RunSimulationAction()); - pm.add(new PlotSimulationAction()); + + // Context menu + pm = new JPopupMenu(); + pm.add(editSimulationAction); + pm.add(duplicateSimulationAction); + pm.add(deleteSimulationAction); + pm.addSeparator(); + pm.add(runSimulationAction); + pm.add(plotSimulationAction); // Mouse listener to act on double-clicks @@ -496,11 +211,14 @@ public class SimulationPanel extends JPanel { }); simulationTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - private int previousRow = -1; + private int previousSelectedRow = -1; + private int previousSelectedRowCount = 0; public void valueChanged(ListSelectionEvent event) { - if (simulationTable.getSelectedRow() != previousRow) { + if ((simulationTable.getSelectedRow() != previousSelectedRow) || + (simulationTable.getSelectedRowCount() != previousSelectedRowCount)) { updateButtonStates(); - previousRow = simulationTable.getSelectedRow(); + previousSelectedRow = simulationTable.getSelectedRow(); + previousSelectedRowCount = simulationTable.getSelectedRowCount(); } } }); @@ -532,6 +250,19 @@ public class SimulationPanel extends JPanel { updateButtonStates(); } + private void newSimulation() { + Simulation sim = new Simulation(document.getRocket()); + sim.setName(document.getNextSimulationName()); + + int n = document.getSimulationCount(); + document.addSimulation(sim); + simulationTableModel.fireTableDataChanged(); + simulationTable.clearSelection(); + simulationTable.addRowSelectionInterval(n, n); + + openDialog(false, sim); + } + private void plotSimulation() { int selected = simulationTable.getSelectedRow(); if (selected < 0) { @@ -690,23 +421,11 @@ public class SimulationPanel extends JPanel { } private void updateButtonStates() { - int[] selection = simulationTable.getSelectedRows(); - if (selection.length == 0) { - editButton.setEnabled(false); - runButton.setEnabled(false); - deleteButton.setEnabled(false); - plotButton.setEnabled(false); - } else { - if (selection.length > 1) { - plotButton.setEnabled(false); - } else { - plotButton.setEnabled(true); - } - editButton.setEnabled(true); - runButton.setEnabled(true); - deleteButton.setEnabled(true); - } - + editSimulationAction.updateEnabledState(); + deleteSimulationAction.updateEnabledState(); + runSimulationAction.updateEnabledState(); + plotSimulationAction.updateEnabledState(); + duplicateSimulationAction.updateEnabledState(); } /// when the simulation tab is selected this run outdated simulated if appropriate. @@ -778,7 +497,31 @@ public class SimulationPanel extends JPanel { } } - class EditSimulationAction extends AbstractAction { + private abstract static class SimulationAction extends AbstractAction { + private static final long serialVersionUID = 1L; + + public abstract void updateEnabledState(); + } + + class NewSimulationAction extends SimulationAction { + public NewSimulationAction() { + putValue(NAME, trans.get("simpanel.but.newsimulation")); + this.putValue(MNEMONIC_KEY, KeyEvent.VK_N); + this.putValue(SMALL_ICON, Icons.FILE_NEW); + } + + @Override + public void actionPerformed(ActionEvent e) { + newSimulation(); + } + + @Override + public void updateEnabledState() { + setEnabled(true); + } + } + + class EditSimulationAction extends SimulationAction { public EditSimulationAction() { putValue(NAME, trans.get("simpanel.pop.edit")); this.putValue(MNEMONIC_KEY, KeyEvent.VK_E); @@ -790,9 +533,14 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { editSimulation(); } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() == 1); + } } - class RunSimulationAction extends AbstractAction { + class RunSimulationAction extends SimulationAction { public RunSimulationAction() { putValue(NAME, trans.get("simpanel.pop.run")); putValue(SMALL_ICON, Icons.SIM_RUN); @@ -802,9 +550,14 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { runSimulation(); } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() > 0); + } } - class DeleteSimulationAction extends AbstractAction { + class DeleteSimulationAction extends SimulationAction { public DeleteSimulationAction() { putValue(NAME, trans.get("simpanel.pop.delete")); putValue(MNEMONIC_KEY, KeyEvent.VK_D); @@ -816,9 +569,14 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { deleteSimulation(); } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() > 0); + } } - class PlotSimulationAction extends AbstractAction { + class PlotSimulationAction extends SimulationAction { public PlotSimulationAction() { putValue(NAME, trans.get("simpanel.pop.plot")); putValue(SMALL_ICON, Icons.SIM_PLOT); @@ -828,9 +586,14 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { plotSimulation(); } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() == 1); + } } - class DuplicateSimulationAction extends AbstractAction { + class DuplicateSimulationAction extends SimulationAction { public DuplicateSimulationAction() { putValue(NAME, trans.get("simpanel.pop.duplicate")); putValue(MNEMONIC_KEY, KeyEvent.VK_D); @@ -842,7 +605,12 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { duplicateSimulation(); } - } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() > 0); + } + } public static class CellTransferable implements Transferable { @@ -955,6 +723,254 @@ public class SimulationPanel extends JPanel { return tip; } + } + private class SimulationTableModel extends ColumnTableModel { + private static final long serialVersionUID = 8686456963492628476L; + + public SimulationTableModel() { + super( + //// Status and warning column + new Column("") { + private JLabel label = null; + + @Override + public Object getValueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + // Initialize the label + if (label == null) { + label = new StyledLabel(2f); + label.setIconTextGap(1); + // label.setFont(label.getFont().deriveFont(Font.BOLD)); + } + + // Set simulation status icon + Simulation.Status status = document.getSimulation(row).getStatus(); + label.setIcon(Icons.SIMULATION_STATUS_ICON_MAP.get(status)); + + + // Set warning marker + if (status == Simulation.Status.NOT_SIMULATED || + status == Simulation.Status.EXTERNAL) { + + label.setText(""); + + } else { + + WarningSet w = document.getSimulation(row).getSimulatedWarnings(); + if (w == null) { + label.setText(""); + } else if (w.isEmpty()) { + label.setForeground(OK_COLOR); + label.setText(OK_TEXT); + } else { + label.setForeground(WARNING_COLOR); + label.setText(WARNING_TEXT); + } + } + + return label; + } + + @Override + public int getExactWidth() { + return 36; + } + + @Override + public Class getColumnClass() { + return JLabel.class; + } + }, + + //// Simulation name + //// 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; + } + + @Override + public Comparator getComparator() { + return new AlphanumComparator(); + } + }, + + //// Simulation configuration + new Column(trans.get("simpanel.col.Configuration")) { + @Override + public Object getValueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) { + return null; + } + + Rocket rkt = document.getRocket(); + FlightConfigurationId fcid = document.getSimulation(row).getId(); + return descriptor.format(rkt, fcid); + } + + @Override + public int getDefaultWidth() { + return 125; + } + }, + + //// Launch rod velocity + new ValueColumn(trans.get("simpanel.col.Velocityoffrod"), UnitGroup.UNITS_VELOCITY) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getLaunchRodVelocity(); + } + + }, + + //// Apogee + new ValueColumn(trans.get("simpanel.col.Apogee"), UnitGroup.UNITS_DISTANCE) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getMaxAltitude(); + } + }, + + //// Velocity at deployment + new ValueColumn(trans.get("simpanel.col.Velocityatdeploy"), UnitGroup.UNITS_VELOCITY) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getDeploymentVelocity(); + } + }, + + //// Deployment Time from Apogee + new ValueColumn(trans.get("simpanel.col.OptimumCoastTime"), + trans.get("simpanel.col.OptimumCoastTime.ttip"), UnitGroup.UNITS_SHORT_TIME) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null || data.getBranchCount() == 0) + return null; + + double val = data.getBranch(0).getOptimumDelay(); + if (Double.isNaN(val)) { + return null; + } + return val; + } + }, + + //// Maximum velocity + new ValueColumn(trans.get("simpanel.col.Maxvelocity"), UnitGroup.UNITS_VELOCITY) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getMaxVelocity(); + } + }, + + //// Maximum acceleration + new ValueColumn(trans.get("simpanel.col.Maxacceleration"), UnitGroup.UNITS_ACCELERATION) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getMaxAcceleration(); + } + }, + + //// Time to apogee + new ValueColumn(trans.get("simpanel.col.Timetoapogee"), UnitGroup.UNITS_FLIGHT_TIME) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getTimeToApogee(); + } + }, + + //// Flight time + new ValueColumn(trans.get("simpanel.col.Flighttime"), UnitGroup.UNITS_FLIGHT_TIME) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getFlightTime(); + } + }, + + //// Ground hit velocity + new ValueColumn(trans.get("simpanel.col.Groundhitvelocity"), UnitGroup.UNITS_VELOCITY) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getGroundHitVelocity(); + } + } + ); + } + + @Override + public int getRowCount() { + return document.getSimulationCount(); + } } } diff --git a/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java b/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java index a02e626f9..a638ba8d0 100644 --- a/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java +++ b/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java @@ -6,6 +6,9 @@ import javax.swing.ToolTipManager; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.components.BasicTree; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + @SuppressWarnings("serial") public class ComponentTree extends BasicTree { @@ -13,7 +16,21 @@ public class ComponentTree extends BasicTree { public ComponentTree(OpenRocketDocument document) { super(); this.setModel(new ComponentTreeModel(document.getRocket(), this)); - + + addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { } + + @Override + public void keyPressed(KeyEvent e) { + if ((e.getKeyCode() == KeyEvent.VK_A) && ((e.getModifiersEx() & KeyEvent.META_DOWN_MASK) != 0)) { + setSelectionInterval(1, getRowCount()); // Don't select the rocket (row 0) + } + } + + @Override + public void keyReleased(KeyEvent e) { } + }); this.setCellRenderer(new ComponentTreeRenderer()); this.setDragEnabled(true);