Restore 15.03 selection behavior for flight config

Restore the behavior from the 15.03 version of the flight configuration
panel. Selected flight configuration is synchronized with the rocket
panel where the design is being done and vice versa.

Fixes #916

Signed-off-by: Billy Olsen <billy.olsen@gmail.com>
This commit is contained in:
Billy Olsen 2021-06-13 20:45:31 -07:00
parent 965311ff4e
commit e547c7c3e8
3 changed files with 89 additions and 41 deletions

View File

@ -1,14 +1,17 @@
package net.sf.openrocket.gui.components; package net.sf.openrocket.gui.components;
import java.util.EventObject;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.MutableComboBoxModel; import javax.swing.MutableComboBoxModel;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.ListDataListener; import javax.swing.event.ListDataListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener; import javax.swing.event.PopupMenuListener;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.FlightConfigurationId; import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.util.StateChangeListener;
// combobox for flight configurations // combobox for flight configurations
// this is insane -- it appears the only way to reconstruct a // this is insane -- it appears the only way to reconstruct a
@ -17,7 +20,7 @@ import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
// to the combobox or to its model) is to reconstruct the model. This // to the combobox or to its model) is to reconstruct the model. This
// is done quickly enough I might as well just do it every time the // is done quickly enough I might as well just do it every time the
// combobox is opened, rather than trying to watch and see if it's needed. // combobox is opened, rather than trying to watch and see if it's needed.
public class ConfigurationComboBox extends JComboBox<FlightConfiguration> { public class ConfigurationComboBox extends JComboBox<FlightConfiguration> implements StateChangeListener {
public class ConfigurationModel implements MutableComboBoxModel<FlightConfiguration> { public class ConfigurationModel implements MutableComboBoxModel<FlightConfiguration> {
private final Rocket rkt; private final Rocket rkt;
@ -77,20 +80,25 @@ public class ConfigurationComboBox extends JComboBox<FlightConfiguration> {
private final Rocket rkt; private final Rocket rkt;
public ConfigurationComboBox(Rocket _rkt) { public ConfigurationComboBox(Rocket _rkt) {
rkt = _rkt; rkt = _rkt;
setModel(new ConfigurationModel(rkt)); setModel(new ConfigurationModel(rkt));
rkt.addChangeListener(this);
addPopupMenuListener(new PopupMenuListener()
{ addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) {} public void popupMenuCanceled(PopupMenuEvent e) {}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
{ setModel(new ConfigurationModel(rkt));
setModel(new ConfigurationModel(rkt)); }
}
});
});
} }
@Override
public void stateChanged(EventObject e) {
this.repaint();
this.revalidate();
}
} }

View File

@ -8,6 +8,7 @@ import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.border.Border; import javax.swing.border.Border;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
@ -24,6 +25,7 @@ import net.sf.openrocket.formatting.RocketDescriptor;
import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent; import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent;
import net.sf.openrocket.rocketcomponent.FlightConfigurationId; import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Rocket;
@ -32,7 +34,7 @@ import net.sf.openrocket.util.Pair;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public abstract class FlightConfigurablePanel<T extends FlightConfigurableComponent> extends JPanel { public abstract class FlightConfigurablePanel<T extends FlightConfigurableComponent> extends JPanel implements ComponentChangeListener {
protected static final Translator trans = Application.getTranslator(); protected static final Translator trans = Application.getTranslator();
private static final Logger log = LoggerFactory.getLogger(FlightConfigurablePanel.class); private static final Logger log = LoggerFactory.getLogger(FlightConfigurablePanel.class);
@ -46,7 +48,7 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
super(new MigLayout("fill")); super(new MigLayout("fill"));
this.flightConfigurationPanel = flightConfigurationPanel; this.flightConfigurationPanel = flightConfigurationPanel;
this.rocket = rocket; this.rocket = rocket;
table = initializeTable(); table = doTableInitialization();
installTableListener(); installTableListener();
synchronizeConfigurationSelection(); synchronizeConfigurationSelection();
@ -54,7 +56,7 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
public void fireTableDataChanged() { public void fireTableDataChanged() {
int selectedRow = table.getSelectedRow(); int selectedRow = table.getSelectedRow();
int selectedColumn = table.getSelectedColumn(); int selectedColumn = table.getSelectedColumn();
this.rocket.fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); this.rocket.fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
((AbstractTableModel)table.getModel()).fireTableDataChanged(); ((AbstractTableModel)table.getModel()).fireTableDataChanged();
restoreSelection(selectedRow,selectedColumn); restoreSelection(selectedRow,selectedColumn);
@ -62,15 +64,41 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
} }
protected abstract void updateButtonState(); protected abstract void updateButtonState();
@Override
public void componentChanged(ComponentChangeEvent e) {
this.synchronizeConfigurationSelection();
}
/**
* Initialize the table using the specific implementation's initializeTable
* method and then select the row to match what the rocket's current selected
* configuration is.
*
* @return the JTable created
*/
private final JTable doTableInitialization() {
JTable table = this.initializeTable();
FlightConfigurationId current = this.rocket.getSelectedConfiguration().getFlightConfigurationID();
int col = (table.getColumnCount() > 1) ? 1 : 0;
for (int row = 0; row < table.getRowCount(); row++) {
FlightConfigurationId rowFCID = rocket.getId(row);
if (rowFCID.equals(current)) {
table.changeSelection(row, col, false, false);
break;
}
}
return table;
}
protected final void synchronizeConfigurationSelection() { protected final void synchronizeConfigurationSelection() {
FlightConfigurationId defaultFCID = rocket.getSelectedConfiguration().getFlightConfigurationID(); FlightConfigurationId currentRocketFCID = rocket.getSelectedConfiguration().getFlightConfigurationID();
FlightConfigurationId selectedFCID = getSelectedConfigurationId(); FlightConfigurationId selectedFCID = getSelectedConfigurationId();
if ( selectedFCID == null ) { if ( currentRocketFCID == FlightConfigurationId.DEFAULT_VALUE_FCID ) {
// need to unselect // need to unselect
table.clearSelection(); table.clearSelection();
} else if ( !defaultFCID.equals(selectedFCID)){ } else if ( !currentRocketFCID.equals(selectedFCID)){
// Need to change selection // Need to change selection
// We'll select the correct row, in the currently selected column. // We'll select the correct row, in the currently selected column.
int col = table.getSelectedColumn(); int col = table.getSelectedColumn();
@ -80,8 +108,8 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
for( int rowNum = 0; rowNum < table.getRowCount(); rowNum++ ) { for( int rowNum = 0; rowNum < table.getRowCount(); rowNum++ ) {
FlightConfigurationId rowFCID = rocket.getId(rowNum ); FlightConfigurationId rowFCID = rocket.getId(rowNum );
if ( rowFCID.equals(selectedFCID) ) { if ( rowFCID.equals(currentRocketFCID) ) {
table.changeSelection(rowNum, col, true, false); table.changeSelection(rowNum, col, false, false);
break; break;
} }
} }
@ -108,16 +136,21 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
if ( e.getValueIsAdjusting() ) { if ( e.getValueIsAdjusting() ) {
return; return;
} }
// int firstrow = e.getFirstIndex();
// int lastrow = e.getLastIndex(); /* Find the selected row and set it as the current selected configuration
// ListSelectionModel model = (ListSelectionModel) e.getSource(); * for the rocket. This will propagate the event to ensure that other
// for( int row = firstrow; row <= lastrow; row ++) { * pieces of the UI are updated and match the table selection.
// if ( model.isSelectedIndex(row) ) { */
// FlightConfigurationID fcid = (FlightConfigurationID) table.getValueAt(row, table.convertColumnIndexToView(0)); int firstrow = e.getFirstIndex();
// FlightConfiguration config = rocket.getConfigurationSet().get(fcid); int lastrow = e.getLastIndex();
// return; ListSelectionModel model = (ListSelectionModel) e.getSource();
// } for( int row = firstrow; row <= lastrow; row ++) {
// } if ( model.isSelectedIndex(row) ) {
FlightConfigurationId fcid = (FlightConfigurationId) table.getValueAt(row, table.convertColumnIndexToView(0));
rocket.setSelectedConfiguration(fcid);
return;
}
}
} }
}); });

View File

@ -44,11 +44,6 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
private final static int RECOVERY_TAB_INDEX = 1; private final static int RECOVERY_TAB_INDEX = 1;
private final static int SEPARATION_TAB_INDEX = 2; private final static int SEPARATION_TAB_INDEX = 2;
@Override
public void stateChanged(EventObject e) {
updateButtonState();
}
public FlightConfigurationPanel(OpenRocketDocument doc) { public FlightConfigurationPanel(OpenRocketDocument doc) {
super(new MigLayout("fill","[grow][][][][][grow]")); super(new MigLayout("fill","[grow][][][][][grow]"));
@ -77,7 +72,12 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
newConfButton.addActionListener(new ActionListener() { newConfButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
addOrCopyConfiguration(false); addOrCopyConfiguration(false);
int lastRow = motorConfigurationPanel.table.getRowCount() - 1;
int lastCol = motorConfigurationPanel.table.getColumnCount() - 1;
motorConfigurationPanel.table.setRowSelectionInterval(lastRow, lastRow);
motorConfigurationPanel.table.setColumnSelectionInterval(lastCol, lastCol);
configurationChanged(); configurationChanged();
} }
@ -146,7 +146,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
newConfig = new FlightConfiguration(rocket, null); newConfig = new FlightConfiguration(rocket, null);
newId = newConfig.getId(); newId = newConfig.getId();
} }
// associate configuration with Id and select it // associate configuration with Id and select it
rocket.setFlightConfiguration(newId, newConfig); rocket.setFlightConfiguration(newId, newConfig);
rocket.setSelectedConfiguration(newId); rocket.setSelectedConfiguration(newId);
@ -216,4 +216,11 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
} }
@Override
public void stateChanged(EventObject e) {
updateButtonState();
motorConfigurationPanel.synchronizeConfigurationSelection();
recoveryConfigurationPanel.synchronizeConfigurationSelection();
separationConfigurationPanel.synchronizeConfigurationSelection();
}
} }