From 2839dfd4dd1da8afc2f1a0f595dd17a15242d702 Mon Sep 17 00:00:00 2001 From: Joe Pfeiffer Date: Thu, 24 May 2018 12:38:09 -0600 Subject: [PATCH] Cleared up problem with blank combobox popups after adding flight configurations. (1) Created new ConfigurationComboBox, extended from JComboBox, with a listener for popup opens that connects to a new ConfigurationModel. (2) Removed some cruft from ConfigurationModel and made it a nested class within ConfigurationComboBox. (3) Updated ComponentAnalysisDialog, RocketPanel, and SimulationEditDialog to use ConfigurationComboBox. --- .../gui/components/ConfigurationComboBox.java | 96 +++++++++++++++++++ .../gui/components/ConfigurationModel.java | 86 ----------------- .../gui/dialogs/ComponentAnalysisDialog.java | 6 +- .../gui/scalefigure/RocketPanel.java | 8 +- .../gui/simulation/SimulationEditDialog.java | 6 +- 5 files changed, 102 insertions(+), 100 deletions(-) create mode 100644 swing/src/net/sf/openrocket/gui/components/ConfigurationComboBox.java delete mode 100644 swing/src/net/sf/openrocket/gui/components/ConfigurationModel.java diff --git a/swing/src/net/sf/openrocket/gui/components/ConfigurationComboBox.java b/swing/src/net/sf/openrocket/gui/components/ConfigurationComboBox.java new file mode 100644 index 000000000..16eed7a4c --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/components/ConfigurationComboBox.java @@ -0,0 +1,96 @@ +package net.sf.openrocket.gui.components; + +import javax.swing.JComboBox; +import javax.swing.MutableComboBoxModel; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.ListDataListener; +import javax.swing.event.PopupMenuListener; + +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.rocketcomponent.FlightConfiguration; +import net.sf.openrocket.rocketcomponent.FlightConfigurationId; + +// combobox for flight configurations +// this is insane -- it appears the only way to reconstruct a +// JComboBox properly after adding a new entry (when added to the +// underlying data structure being displayed, not when added directly +// 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 +// combobox is opened, rather than trying to watch and see if it's needed. +public class ConfigurationComboBox extends JComboBox { + public class ConfigurationModel implements MutableComboBoxModel { + + private final Rocket rkt; + + public ConfigurationModel(final Rocket _rkt) { + this.rkt = _rkt; + } + + @Override + public FlightConfiguration getSelectedItem() { + return rkt.getSelectedConfiguration(); + } + + @Override + public void setSelectedItem(Object nextItem) { + if( nextItem instanceof FlightConfiguration ){ + FlightConfigurationId selectedId = ((FlightConfiguration)nextItem).getId(); + rkt.setSelectedConfiguration(selectedId); + } + } + + @Override + public FlightConfiguration getElementAt( final int configIndex) { + return rkt.getFlightConfigurationByIndex(configIndex, true); + } + + @Override + public int getSize() { + // plus the default config + return rkt.getConfigurationCount()+1; + } + + // ====== MutableComboBoxModel Functions ====== + // these functions don't need to do anything, just being a 'mutable' version of the combo box + // is enough to allow updating the UI + + @Override + public void addListDataListener(ListDataListener l) {} + + @Override + public void removeListDataListener(ListDataListener l) {} + + @Override + public void addElement(FlightConfiguration arg0) {} + + @Override + public void insertElementAt(FlightConfiguration arg0, int arg1) {} + + @Override + public void removeElement(Object arg0) {} + + @Override + public void removeElementAt(int arg0) {} + + } + + private final Rocket rkt; + + public ConfigurationComboBox(Rocket _rkt) { + rkt = _rkt; + setModel(new ConfigurationModel(rkt)); + + addPopupMenuListener(new PopupMenuListener() + { + public void popupMenuCanceled(PopupMenuEvent e) {} + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} + + public void popupMenuWillBecomeVisible(PopupMenuEvent e) + { + setModel(new ConfigurationModel(rkt)); + } + + }); + + } +} diff --git a/swing/src/net/sf/openrocket/gui/components/ConfigurationModel.java b/swing/src/net/sf/openrocket/gui/components/ConfigurationModel.java deleted file mode 100644 index ebec09ac6..000000000 --- a/swing/src/net/sf/openrocket/gui/components/ConfigurationModel.java +++ /dev/null @@ -1,86 +0,0 @@ -package net.sf.openrocket.gui.components; - -import net.sf.openrocket.rocketcomponent.FlightConfigurationId; -import net.sf.openrocket.rocketcomponent.Rocket; -import net.sf.openrocket.rocketcomponent.FlightConfiguration; -import net.sf.openrocket.util.StateChangeListener; - -import javax.swing.*; -import javax.swing.event.ListDataListener; - -import java.util.EventObject; - -public class ConfigurationModel implements MutableComboBoxModel, StateChangeListener { - - private final Rocket rkt; - private final JComboBox combo; - - public ConfigurationModel( final Rocket _rkt, final JComboBox _combo) { - this.rkt = _rkt; - this.combo = _combo; - } - - @Override - public void stateChanged(EventObject eo) { - combo.revalidate(); - combo.repaint(); - } - - - @Override - public Object getSelectedItem() { - return rkt.getSelectedConfiguration(); - } - - - @Override - public void setSelectedItem(Object nextItem) { - if( nextItem instanceof FlightConfiguration ){ - FlightConfigurationId selectedId = ((FlightConfiguration)nextItem).getId(); - rkt.setSelectedConfiguration(selectedId); - } - } - - @Override - public void addListDataListener(ListDataListener l) { - // let the rocket send events, if necessary - // ignore any listen requests here... - } - - - public FlightConfiguration getElementAt( final int configIndex) { - return rkt.getFlightConfigurationByIndex(configIndex, true); - } - - - @Override - public int getSize() { - // plus the default config - return rkt.getConfigurationCount()+1; - } - - - @Override - public void removeListDataListener(ListDataListener l) { - // delegate event handling to the rocket - // ignore any listen requests here... - } - - // ====== MutableComboBoxModel Functions ====== - // these functions don't need to do anything, just being a 'mutable' version of the combo box - // is enough to allow updating the UI - - @Override - public void addElement(FlightConfiguration arg0) {} - - @Override - public void insertElementAt(FlightConfiguration arg0, int arg1) {} - - @Override - public void removeElement(Object arg0) {} - - @Override - public void removeElementAt(int arg0) {} - - -} diff --git a/swing/src/net/sf/openrocket/gui/dialogs/ComponentAnalysisDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/ComponentAnalysisDialog.java index 71d7eccba..d6b90b6ba 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/ComponentAnalysisDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/ComponentAnalysisDialog.java @@ -47,7 +47,7 @@ import net.sf.openrocket.gui.adaptors.ColumnTable; import net.sf.openrocket.gui.adaptors.ColumnTableModel; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.components.BasicSlider; -import net.sf.openrocket.gui.components.ConfigurationModel; +import net.sf.openrocket.gui.components.ConfigurationComboBox; import net.sf.openrocket.gui.components.StageSelector; import net.sf.openrocket.gui.components.StyledLabel; import net.sf.openrocket.gui.components.UnitSelector; @@ -176,9 +176,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe label.setHorizontalAlignment(JLabel.RIGHT); panel.add(label, "growx, right"); - final JComboBox configComboBox = new JComboBox<>(); - final ConfigurationModel configModel = new ConfigurationModel(rkt, configComboBox); - configComboBox.setModel( configModel); + final ConfigurationComboBox configComboBox = new ConfigurationComboBox(rkt); panel.add( configComboBox, "wrap"); diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index faf1a2752..6e1b0e3a2 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -38,7 +38,7 @@ import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.components.BasicSlider; -import net.sf.openrocket.gui.components.ConfigurationModel; +import net.sf.openrocket.gui.components.ConfigurationComboBox; import net.sf.openrocket.gui.components.StageSelector; import net.sf.openrocket.gui.components.UnitSelector; import net.sf.openrocket.gui.configdialog.ComponentConfigDialog; @@ -318,13 +318,9 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change label.setHorizontalAlignment(JLabel.RIGHT); add(label, "growx, right"); - final JComboBox configComboBox = new JComboBox<>(); - final ConfigurationModel configModel = new ConfigurationModel(rkt, configComboBox); - rkt.addChangeListener( configModel ); - configComboBox.setModel(configModel); + final ConfigurationComboBox configComboBox = new ConfigurationComboBox(rkt); add(configComboBox, "wrap, width 16%, wmin 100"); - // Create slider and scroll pane DoubleModel theta = new DoubleModel(figure, "Rotation", UnitGroup.UNITS_ANGLE, 0, 2 * Math.PI); diff --git a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java index cd98327c6..a57ae77bb 100644 --- a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java +++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java @@ -21,7 +21,7 @@ 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.gui.components.ConfigurationModel; +import net.sf.openrocket.gui.components.ConfigurationComboBox; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.FlightConfiguration; @@ -148,9 +148,7 @@ public class SimulationEditDialog extends JDialog { panel.add(label, "growx 0, gapright para"); final Rocket rkt = document.getRocket(); - final JComboBox configComboBox = new JComboBox<>(); - final ConfigurationModel configModel = new ConfigurationModel(rkt, configComboBox); - configComboBox.setModel( configModel); + final ConfigurationComboBox configComboBox = new ConfigurationComboBox(rkt); //// Select the motor configuration to use. configComboBox.setToolTipText(trans.get("simedtdlg.combo.ttip.Flightcfg"));