diff --git a/swing/src/net/sf/openrocket/gui/adaptors/CustomFocusTraversalPolicy.java b/swing/src/net/sf/openrocket/gui/adaptors/CustomFocusTraversalPolicy.java index d5a71a716..00f10b01c 100644 --- a/swing/src/net/sf/openrocket/gui/adaptors/CustomFocusTraversalPolicy.java +++ b/swing/src/net/sf/openrocket/gui/adaptors/CustomFocusTraversalPolicy.java @@ -22,11 +22,15 @@ public class CustomFocusTraversalPolicy extends FocusTraversalPolicy { } public Component getComponentAfter(Container focusCycleRoot, Component aComponent) { + // Get the next component int idx = (order.indexOf(aComponent) + 1) % order.size(); + + // If the next component is disabled, loop for the next enabled one int count = 0; - while (!order.get(idx).isEnabled()) { + while (!order.get(idx).isEnabled() || !order.get(idx).isShowing() || !order.get(idx).isVisible()) { idx = (idx + 1) % order.size(); count++; + // No active component found, fall back to the original component if (count == order.size()) return aComponent; } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java b/swing/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java index a4658dd19..42f4cc225 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java @@ -1,10 +1,12 @@ package net.sf.openrocket.gui.configdialog; import java.awt.Color; +import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.lang.reflect.Method; import java.util.EventObject; +import java.util.List; import javax.swing.JPanel; import javax.swing.JColorChooser; @@ -84,6 +86,8 @@ public class AppearancePanel extends JPanel { private JCheckBox customInside = null; + private final List order; // Component traversal order + /** * A non-unit that adjusts by a small amount, suitable for values that are * on the 0-1 scale @@ -198,10 +202,17 @@ public class AppearancePanel extends JPanel { } } - - public AppearancePanel(final OpenRocketDocument document, final RocketComponent c, final JDialog parent) { + /** + * Appearance panel for the appearance of a rocket component. + * @param document current document + * @param c component to change the appearance of + * @param parent parent dialog + * @param order component traversal order object of the component config dialog + */ + public AppearancePanel(final OpenRocketDocument document, final RocketComponent c, final JDialog parent, List order) { super(new MigLayout("fill", "[150][grow][150][grow]")); + this.order = order; defaultAppearance = DefaultAppearance.getDefaultAppearance(c); previousUserSelectedAppearance = c.getAppearance(); @@ -298,6 +309,7 @@ public class AppearancePanel extends JPanel { add(new StyledLabel(trans.get("RocketCompCfg.lbl.Figurestyle"), Style.BOLD)); add(colorDefault); + order.add(colorDefault); JButton button = new SelectColorButton( trans.get("RocketCompCfg.but.Saveasdefstyle")); @@ -324,6 +336,7 @@ public class AppearancePanel extends JPanel { add(new JLabel(trans.get("RocketCompCfg.lbl.Componentcolor"))); fDefault.addEnableComponent(figureColorButton, false); add(figureColorButton); + order.add(figureColorButton); } {// Line Style @@ -341,6 +354,7 @@ public class AppearancePanel extends JPanel { fDefault.addEnableComponent(combo, false); add(combo, "growx, wrap"); + order.add(combo); } add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx"); @@ -370,8 +384,9 @@ public class AppearancePanel extends JPanel { customInside.setText(trans.get(tr_insideOutside)); customInside.setToolTipText(trans.get(tr_insideOutside_ttip)); add(customInside, "span 2"); + order.add(customInside); - // Checkbox to set edges the same as inside/outside + // Combobox for setting the edge appearance from inside/outside appearance JLabel edgesText = new JLabel(trans.get("AppearanceCfg.lbl.AppearanceEdges")); add(edgesText); String[] options = new String[] {trans.get(tr_outside), trans.get(tr_inside)}; @@ -383,6 +398,7 @@ public class AppearancePanel extends JPanel { edgesComboBox.setSelectedItem(trans.get(tr_outside)); } add(edgesComboBox, "growx, left, wrap"); + order.add(edgesComboBox); edgesText.setToolTipText(trans.get("AppearanceCfg.lbl.ttip.AppearanceEdges")); edgesComboBox.setToolTipText(trans.get("AppearanceCfg.lbl.ttip.AppearanceEdges")); @@ -544,6 +560,7 @@ public class AppearancePanel extends JPanel { }); materialDefault.setText(trans.get("AppearanceCfg.lbl.Usedefault")); panel.add(materialDefault, "wrap"); + order.add(materialDefault); // Texture File panel.add(new JLabel(trans.get("AppearanceCfg.lbl.Texture"))); @@ -551,6 +568,7 @@ public class AppearancePanel extends JPanel { mDefault.addEnableComponent(textureDropDown, false); p.add(textureDropDown, "grow"); panel.add(p, "span 3, growx, wrap"); + order.add(textureDropDown); JButton editBtn = new SelectColorButton( trans.get("AppearanceCfg.but.edit")); editBtn.setEnabled(builder.getImage() != null); @@ -585,6 +603,7 @@ public class AppearancePanel extends JPanel { panel.add(new JLabel(trans.get("AppearanceCfg.lbl.color.Color"))); mDefault.addEnableComponent(colorButton, false); panel.add(colorButton); + order.add(colorButton); // Scale panel.add(new JLabel(trans.get("AppearanceCfg.lbl.texture.scale"))); @@ -595,6 +614,7 @@ public class AppearancePanel extends JPanel { scaleU.setEditor(new SpinnerEditor(scaleU)); mDefault.addEnableComponent(scaleU, false); panel.add(scaleU, "w 40"); + order.add(((SpinnerEditor) scaleU.getEditor()).getTextField()); panel.add(new JLabel("y:")); JSpinner scaleV = new JSpinner(new DoubleModel(builder, "ScaleY", @@ -602,6 +622,7 @@ public class AppearancePanel extends JPanel { scaleV.setEditor(new SpinnerEditor(scaleV)); mDefault.addEnableComponent(scaleV, false); panel.add(scaleV, "wrap, w 40"); + order.add(((SpinnerEditor) scaleV.getEditor()).getTextField()); // Shine panel.add(new JLabel(trans.get("AppearanceCfg.lbl.shine"))); @@ -622,6 +643,7 @@ public class AppearancePanel extends JPanel { panel.add(spinShine, "split 3, w 60"); panel.add(unitShine); panel.add(slideShine, "w 50, growx"); + order.add(order.indexOf(colorButton) + 1, ((SpinnerEditor) spinShine.getEditor()).getTextField()); // Offset panel.add(new JLabel(trans.get("AppearanceCfg.lbl.texture.offset"))); @@ -632,6 +654,7 @@ public class AppearancePanel extends JPanel { offsetU.setEditor(new SpinnerEditor(offsetU)); mDefault.addEnableComponent(offsetU, false); panel.add(offsetU, "w 40"); + order.add(((SpinnerEditor) offsetU.getEditor()).getTextField()); panel.add(new JLabel("y:")); JSpinner offsetV = new JSpinner(new DoubleModel(builder, "OffsetV", @@ -639,6 +662,7 @@ public class AppearancePanel extends JPanel { offsetV.setEditor(new SpinnerEditor(offsetV)); mDefault.addEnableComponent(offsetV, false); panel.add(offsetV, "wrap, w 40"); + order.add(((SpinnerEditor) offsetV.getEditor()).getTextField()); // Opacity panel.add(new JLabel(trans.get("AppearanceCfg.lbl.opacity"))); @@ -656,6 +680,8 @@ public class AppearancePanel extends JPanel { panel.add(spinOpacity, "split 3, w 60"); panel.add(unitOpacity); panel.add(slideOpacity, "w 50, growx"); + order.add(order.indexOf(((SpinnerEditor) spinShine.getEditor()).getTextField()) + 1, + ((SpinnerEditor) spinOpacity.getEditor()).getTextField()); // Rotation panel.add(new JLabel(trans.get("AppearanceCfg.lbl.texture.rotation"))); @@ -665,6 +691,7 @@ public class AppearancePanel extends JPanel { rotation.setEditor(new SpinnerEditor(rotation)); mDefault.addEnableComponent(rotation, false); panel.add(rotation, "split 3, w 50"); + order.add(((SpinnerEditor) rotation.getEditor()).getTextField()); panel.add(new UnitSelector(rotationModel)); BasicSlider bs = new BasicSlider(rotationModel.getSliderModel( -Math.PI, Math.PI)); @@ -680,6 +707,7 @@ public class AppearancePanel extends JPanel { "EdgeMode", list)); mDefault.addEnableComponent(combo, false); panel.add(combo, "wrap"); + order.add(combo); builder.addChangeListener(new StateChangeListener() { double lastOpacity = builder.getOpacity(); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java index 3e64d386f..80ea20c5e 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java @@ -40,8 +40,6 @@ public class BodyTubeConfig extends RocketComponentConfig { JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", "")); - final List order = new ArrayList<>(); // Component traversal order - //// Body tube length panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Bodytubelength"))); @@ -121,16 +119,17 @@ public class BodyTubeConfig extends RocketComponentConfig { //// General and General properties tabbedPane.insertTab(trans.get("BodyTubecfg.tab.General"), null, panel, trans.get("BodyTubecfg.tab.Generalproperties"), 0); - CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); - parent.setFocusTraversalPolicy(policy); tabbedPane.setSelectedIndex(0); - MotorConfig motorConfig = new MotorConfig((MotorMount)c); + MotorConfig motorConfig = new MotorConfig((MotorMount)c, order); tabbedPane.insertTab(trans.get("BodyTubecfg.tab.Motor"), null, motorConfig, trans.get("BodyTubecfg.tab.Motormountconf"), 1); + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); + } @Override diff --git a/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java index 5ebdeed12..c41e9d8a6 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java @@ -182,10 +182,10 @@ public class InnerTubeConfig extends RocketComponentConfig { tabbedPane.insertTab(trans.get("ThicknessRingCompCfg.tab.General"), null, panel, trans.get("ThicknessRingCompCfg.tab.Generalprop"), 0); - MotorConfig motorConfig = new MotorConfig((MotorMount)c); + /*MotorConfig motorConfig = new MotorConfig((MotorMount)c); tabbedPane.insertTab(trans.get("InnerTubeCfg.tab.Motor"), null, motorConfig, - trans.get("InnerTubeCfg.tab.ttip.Motor"), 1); + trans.get("InnerTubeCfg.tab.ttip.Motor"), 1);*/ JPanel tab = clusterTab(); //// Cluster and Cluster configuration diff --git a/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java index a1f4192ca..b5f8737d2 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java @@ -3,6 +3,7 @@ package net.sf.openrocket.gui.configdialog; import java.awt.Component; import java.awt.Container; +import java.util.List; import javax.swing.JCheckBox; import javax.swing.JComboBox; @@ -34,7 +35,7 @@ public class MotorConfig extends JPanel { private final MotorMount mount; private static final Translator trans = Application.getTranslator(); - public MotorConfig(MotorMount motorMount) { + public MotorConfig(MotorMount motorMount, List order) { super(new MigLayout("fill")); this.mount = motorMount; @@ -46,6 +47,7 @@ public class MotorConfig extends JPanel { ////This component is a motor mount check.setText(trans.get("MotorCfg.checkbox.compmotormount")); this.add(check, "wrap"); + order.add(check); final JPanel panel = new JPanel(new MigLayout("fill")); this.add(panel, "grow, wrap"); @@ -60,6 +62,7 @@ public class MotorConfig extends JPanel { JSpinner spin = new JSpinner(dm.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "span, split, width :65lp:"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(dm), "width :30lp:"); panel.add(new BasicSlider(dm.getSliderModel(-0.02, 0.06)), "w 100lp, wrap unrel"); @@ -74,6 +77,7 @@ public class MotorConfig extends JPanel { final EnumModel igEvModel = new EnumModel(motorInstance, "IgnitionEvent", IgnitionEvent.values()); final JComboBox eventBox = new JComboBox( igEvModel); panel.add(eventBox , "growx, wrap"); + order.add(eventBox); // ... and delay //// plus @@ -83,6 +87,7 @@ public class MotorConfig extends JPanel { spin = new JSpinner(dm.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin, 3)); panel.add(spin, "gap rel rel"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); //// seconds panel.add(new JLabel(trans.get("MotorCfg.lbl.seconds")), "wrap unrel"); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java index 4000e15ca..ce6bbfc91 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java @@ -55,8 +55,10 @@ public class RocketComponentConfig extends JPanel { protected final OpenRocketDocument document; protected final RocketComponent component; protected final JTabbedPane tabbedPane; + protected final JDialog parent; private final List invalidatables = new ArrayList(); + protected final List order = new ArrayList<>(); // Component traversal order private JComboBox presetComboBox; private PresetModel presetModel; @@ -80,6 +82,7 @@ public class RocketComponentConfig extends JPanel { this.document = document; this.component = component; + this.parent = parent; // Check the listeners for the same type and massive status allSameType = true; @@ -110,6 +113,7 @@ public class RocketComponentConfig extends JPanel { //// The component name. componentNameField.setToolTipText(trans.get("RocketCompCfg.lbl.Componentname.ttip")); this.add(componentNameField, "growx"); + order.add(componentNameField); if (allSameType && component.getPresetType() != null) { // If the component supports a preset, show the preset selection box. @@ -119,6 +123,7 @@ public class RocketComponentConfig extends JPanel { presetComboBox.setEditable(false); presetComboBox.setToolTipText(trans.get("PresetModel.combo.ttip")); this.add(presetComboBox, "growx 110"); + order.add(presetComboBox); final JButton selectPreset = new SelectColorButton(trans.get("PresetModel.lbl.partsLib")); selectPreset.setToolTipText(trans.get("PresetModel.lbl.partsLib.ttip")); @@ -139,7 +144,7 @@ public class RocketComponentConfig extends JPanel { trans.get("RocketCompCfg.tab.Override.ttip")); if (allMassive) { //// Appearance options - appearancePanel = new AppearancePanel(document, component, parent); + appearancePanel = new AppearancePanel(document, component, parent, order); tabbedPane.addTab(trans.get("RocketCompCfg.tab.Appearance"), null, appearancePanel, trans.get("RocketCompCfg.tab.Appearance.ttip")); } @@ -336,7 +341,7 @@ public class RocketComponentConfig extends JPanel { //// Override the mass or center of gravity of the panel.add(new StyledLabel(trans.get("RocketCompCfg.lbl.Overridemassorcenter") + " " + component.getComponentName() + ":", Style.BOLD), "spanx, wrap 20lp"); - + JCheckBox check; BooleanModel bm; UnitSelector us; @@ -348,6 +353,7 @@ public class RocketComponentConfig extends JPanel { //// Override mass: check.setText(trans.get("RocketCompCfg.checkbox.Overridemass")); panel.add(check, "growx 1, gapright 20lp"); + order.add(check); DoubleModel m = new DoubleModel(component, "OverrideMass", UnitGroup.UNITS_MASS, 0); @@ -355,6 +361,7 @@ public class RocketComponentConfig extends JPanel { spin.setEditor(new SpinnerEditor(spin)); bm.addEnableComponent(spin, true); panel.add(spin, "growx 1"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); us = new UnitSelector(m); bm.addEnableComponent(us, true); @@ -373,6 +380,7 @@ public class RocketComponentConfig extends JPanel { //// Override center of gravity:" check.setText(trans.get("RocketCompCfg.checkbox.Overridecenterofgrav")); panel.add(check, "growx 1, gapright 20lp"); + order.add(check); m = new DoubleModel(component, "OverrideCGX", UnitGroup.UNITS_LENGTH, 0); // Calculate suitable length for slider @@ -410,6 +418,7 @@ public class RocketComponentConfig extends JPanel { spin.setEditor(new SpinnerEditor(spin)); bm.addEnableComponent(spin, true); panel.add(spin, "growx 1"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); us = new UnitSelector(m); bm.addEnableComponent(us, true); @@ -428,6 +437,7 @@ public class RocketComponentConfig extends JPanel { //// Override mass and CG of all subcomponents check.setText(trans.get("RocketCompCfg.checkbox.OverridemassandCG")); panel.add(check, "spanx, wrap 35lp"); + order.add(check); //BEGIN OVERRIDES CD --------------------------------------------------- @@ -438,6 +448,7 @@ public class RocketComponentConfig extends JPanel { //// Override coefficient of drag: check.setText(trans.get("RocketCompCfg.checkbox.SetDragCoeff")); panel.add(check, "growx 1, gapright 20lp"); + order.add(check); m = new DoubleModel(component, "OverrideCD", UnitGroup.UNITS_COEFFICIENT, 0); spin = new JSpinner(m.getSpinnerModel()); @@ -445,6 +456,7 @@ public class RocketComponentConfig extends JPanel { spin.setEditor(new SpinnerEditor(spin)); bm.addEnableComponent(spin, true); panel.add(spin, "growx 1"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); bs = new BasicSlider(m.getSliderModel(0, 1.0)); @@ -481,6 +493,7 @@ public class RocketComponentConfig extends JPanel { commentTextArea.addFocusListener(textFieldListener); panel.add(new JScrollPane(commentTextArea), "grow"); + order.add(commentTextArea); return panel; } @@ -515,6 +528,7 @@ public class RocketComponentConfig extends JPanel { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); sub.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); sub.add(new UnitSelector(m), "growx"); sub.add(new BasicSlider(m.getSliderModel(m0, m2)), "w 100lp, wrap"); @@ -528,6 +542,7 @@ public class RocketComponentConfig extends JPanel { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); sub.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); sub.add(new UnitSelector(m), "growx"); sub.add(new BasicSlider(m.getSliderModel(0, 0.02, 0.2)), "w 100lp, wrap"); @@ -542,6 +557,7 @@ public class RocketComponentConfig extends JPanel { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); sub.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); sub.add(new UnitSelector(m), "growx"); sub.add(new BasicSlider(m.getSliderModel(m0, m2)), "w 100lp, wrap"); @@ -555,6 +571,7 @@ public class RocketComponentConfig extends JPanel { //// Whether the end of the shoulder is capped. check.setToolTipText(trans.get("RocketCompCfg.ttip.Endcapped")); sub.add(check, "spanx"); + order.add(check); panel.add(sub); @@ -582,6 +599,7 @@ public class RocketComponentConfig extends JPanel { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); sub.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); sub.add(new UnitSelector(m), "growx"); sub.add(new BasicSlider(m.getSliderModel(m0, m2)), "w 100lp, wrap"); @@ -595,6 +613,7 @@ public class RocketComponentConfig extends JPanel { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); sub.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); sub.add(new UnitSelector(m), "growx"); sub.add(new BasicSlider(m.getSliderModel(0, 0.02, 0.2)), "w 100lp, wrap"); @@ -609,6 +628,7 @@ public class RocketComponentConfig extends JPanel { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); sub.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); sub.add(new UnitSelector(m), "growx"); sub.add(new BasicSlider(m.getSliderModel(m0, m2)), "w 100lp, wrap"); @@ -622,6 +642,7 @@ public class RocketComponentConfig extends JPanel { //// Whether the end of the shoulder is capped. check.setToolTipText(trans.get("RocketCompCfg.ttip.Endcapped")); sub.add(check, "spanx"); + order.add(check); panel.add(sub);