diff --git a/swing/src/net/sf/openrocket/gui/adaptors/CustomFocusTraversalPolicy.java b/swing/src/net/sf/openrocket/gui/adaptors/CustomFocusTraversalPolicy.java new file mode 100644 index 000000000..5604e5f87 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/adaptors/CustomFocusTraversalPolicy.java @@ -0,0 +1,74 @@ +package net.sf.openrocket.gui.adaptors; + +import java.awt.Component; +import java.awt.Container; +import java.awt.FocusTraversalPolicy; +import java.util.LinkedList; +import java.util.List; + +/** + * Custom adapter class for focus traversal, based on a given order of GUI components + * + * @author Sibo Van Gool + */ +public class CustomFocusTraversalPolicy extends FocusTraversalPolicy { + private final List order; + + /** + * @param order the order of components to traverse + */ + public CustomFocusTraversalPolicy(List order) { + this.order = new LinkedList<>(order); + } + + 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() || !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; + } + return order.get(idx); + } + + public Component getComponentBefore(Container focusCycleRoot, Component aComponent) { + int idx = order.indexOf(aComponent) - 1; + if (idx < 0) { + idx = order.size() - 1; + } + int count = 0; + while (!order.get(idx).isEnabled() || !order.get(idx).isShowing() || !order.get(idx).isVisible()) { + idx = (idx - 1) % order.size(); + count++; + if (count == order.size()) + return aComponent; + } + return order.get(idx); + } + + public Component getDefaultComponent(Container focusCycleRoot) { + return getFirstComponent(focusCycleRoot); + } + + public Component getLastComponent(Container focusCycleRoot) { + int idx = order.size() - 1; + if ((order.get(idx).isEnabled() && order.get(idx).isShowing() && order.get(idx).isVisible())) { + return order.get(idx); + } + return getComponentBefore(focusCycleRoot, order.get(idx)); + } + + public Component getFirstComponent(Container focusCycleRoot) { + int idx = 0; + if ((order.get(idx).isEnabled() && order.get(idx).isShowing() && order.get(idx).isVisible())) { + return order.get(idx); + } + return getComponentAfter(focusCycleRoot, order.get(idx)); + } +} diff --git a/swing/src/net/sf/openrocket/gui/components/BasicSlider.java b/swing/src/net/sf/openrocket/gui/components/BasicSlider.java index 6b182a45d..026641768 100644 --- a/swing/src/net/sf/openrocket/gui/components/BasicSlider.java +++ b/swing/src/net/sf/openrocket/gui/components/BasicSlider.java @@ -26,6 +26,7 @@ public class BasicSlider extends JSlider { super(brm); setOrientation(orientation); setInverted(inverted); + setFocusable(false); setUI(new BasicSliderUI(this)); } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java b/swing/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java index a4658dd19..f19076c96 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(); @@ -276,6 +287,7 @@ public class AppearancePanel extends JPanel { BooleanModel fDefault = new BooleanModel(c.getColor() == null); + final JButton saveAsDefault; {// Style Header Row final JCheckBox colorDefault = new JCheckBox(fDefault); colorDefault.addActionListener(new ActionListener() { @@ -298,10 +310,11 @@ public class AppearancePanel extends JPanel { add(new StyledLabel(trans.get("RocketCompCfg.lbl.Figurestyle"), Style.BOLD)); add(colorDefault); + order.add(colorDefault); - JButton button = new SelectColorButton( + saveAsDefault = new SelectColorButton( trans.get("RocketCompCfg.but.Saveasdefstyle")); - button.addActionListener(new ActionListener() { + saveAsDefault.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (c.getColor() != null) { @@ -316,16 +329,19 @@ public class AppearancePanel extends JPanel { } } }); - fDefault.addEnableComponent(button, false); - add(button, "span 2, align right, wrap"); + fDefault.addEnableComponent(saveAsDefault, false); + add(saveAsDefault, "span 2, align right, wrap"); } {// Figure Color add(new JLabel(trans.get("RocketCompCfg.lbl.Componentcolor"))); fDefault.addEnableComponent(figureColorButton, false); add(figureColorButton); + order.add(figureColorButton); } + order.add(saveAsDefault); + {// Line Style add(new JLabel(trans.get("RocketCompCfg.lbl.Complinestyle"))); @@ -341,6 +357,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 +387,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 +401,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 +563,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 +571,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 +606,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 +617,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 +625,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 +646,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 +657,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 +665,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 +683,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 +694,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 +710,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/AxialStageConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/AxialStageConfig.java index ae1d65b5e..611e67920 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/AxialStageConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/AxialStageConfig.java @@ -9,6 +9,7 @@ import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.components.StyledLabel; @@ -35,6 +36,11 @@ public class AxialStageConfig extends ComponentAssemblyConfig { trans.get("StageConfig.tab.Separation.ttip"), 0); tabbedPane.setSelectedIndex(0); } + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } @@ -46,11 +52,11 @@ public class AxialStageConfig extends ComponentAssemblyConfig { StageSeparationConfiguration sepConfig = stage.getSeparationConfiguration(); - JComboBox combo = new JComboBox( - new EnumModel( sepConfig, "SeparationEvent", SeparationEvent.values())); + JComboBox combo = new JComboBox<>(new EnumModel<>( sepConfig, "SeparationEvent", SeparationEvent.values())); //combo.setSelectedItem(sepConfig); panel.add(combo, ""); + order.add(combo); // ... and delay panel.add(new JLabel(trans.get("StageConfig.separation.lbl.plus")), ""); @@ -59,12 +65,13 @@ public class AxialStageConfig extends ComponentAssemblyConfig { JSpinner spin = new JSpinner(dm.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "width 45"); + order.add(((SpinnerEditor)spin.getEditor()).getTextField()); //// seconds panel.add(new JLabel(trans.get("StageConfig.separation.lbl.seconds")), "wrap unrel"); panel.add(new StyledLabel(CommonStrings.override_description, -1), "spanx, wrap para"); - + return panel; } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java index c2dc1d883..58835dec6 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java @@ -6,13 +6,12 @@ import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSpinner; -import javax.swing.JTextField; -import javax.swing.SwingUtilities; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; import net.sf.openrocket.gui.adaptors.BooleanModel; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.components.BasicSlider; import net.sf.openrocket.gui.components.UnitSelector; @@ -25,12 +24,6 @@ import net.sf.openrocket.rocketcomponent.SymmetricComponent; import net.sf.openrocket.startup.Application; import net.sf.openrocket.unit.UnitGroup; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.Arrays; - @SuppressWarnings("serial") public class BodyTubeConfig extends RocketComponentConfig { @@ -53,6 +46,7 @@ public class BodyTubeConfig extends RocketComponentConfig { spin.setEditor(new SpinnerEditor(spin)); focusElement = spin; panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(length), "growx"); panel.add(new BasicSlider(length.getSliderModel(0, 0.5, maxLength)), "w 100lp, wrap"); @@ -65,6 +59,7 @@ public class BodyTubeConfig extends RocketComponentConfig { spin = new JSpinner(od.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(od), "growx"); panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px"); @@ -74,6 +69,7 @@ public class BodyTubeConfig extends RocketComponentConfig { checkAutoOuterRadius = new JCheckBox(outerAutoAction); checkAutoOuterRadius.setText(trans.get("BodyTubecfg.checkbox.Automatic")); panel.add(checkAutoOuterRadius, "skip, span 2, wrap"); + order.add(checkAutoOuterRadius); updateCheckboxAutoAftRadius(); //// Inner diameter @@ -84,6 +80,7 @@ public class BodyTubeConfig extends RocketComponentConfig { spin = new JSpinner(innerRadiusModel.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(innerRadiusModel), "growx"); panel.add(new BasicSlider(innerRadiusModel.getSliderModel(new DoubleModel(0), od)), "w 100lp, wrap"); @@ -96,6 +93,7 @@ public class BodyTubeConfig extends RocketComponentConfig { spin = new JSpinner(thicknessModel.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(thicknessModel), "growx"); panel.add(new BasicSlider(thicknessModel.getSliderModel(0, 0.01)), "w 100lp, wrap 0px"); @@ -105,10 +103,11 @@ public class BodyTubeConfig extends RocketComponentConfig { check.setText(trans.get("BodyTubecfg.checkbox.Filled")); check.setToolTipText(trans.get("BodyTubecfg.checkbox.Filled.ttip")); panel.add(check, "skip, span 2, wrap"); + order.add(check); //// Material - panel.add(materialPanel(Material.Type.BULK), - "cell 4 0, gapleft paragraph, aligny 0%, spany"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel.add(materialPanel, "cell 4 0, gapleft paragraph, aligny 0%, spany"); //// General and General properties tabbedPane.insertTab(trans.get("BodyTubecfg.tab.General"), null, panel, @@ -116,11 +115,15 @@ public class BodyTubeConfig extends RocketComponentConfig { 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); + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } @Override diff --git a/swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java index 17d5163bf..1659a721c 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java @@ -5,6 +5,7 @@ import javax.swing.JDialog; import javax.swing.JPanel; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; @@ -26,6 +27,11 @@ public class BulkheadConfig extends RingComponentConfig { tabbedPane.insertTab(trans.get("BulkheadCfg.tab.General"), null, tab, trans.get("BulkheadCfg.tab.Generalproperties"), 0); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this panel + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } } \ No newline at end of file diff --git a/swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java index 048116ec1..548bf4b86 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java @@ -5,6 +5,7 @@ import javax.swing.JDialog; import javax.swing.JPanel; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; @@ -28,6 +29,11 @@ public class CenteringRingConfig extends RingComponentConfig { tabbedPane.insertTab(trans.get("CenteringRingCfg.tab.General"), null, tab, trans.get("CenteringRingCfg.tab.Generalproperties"), 0); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this panel + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } } \ No newline at end of file diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java index 4697b2717..f6554f544 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java @@ -58,6 +58,7 @@ public class ComponentAssemblyConfig extends RocketComponentConfig { final ComboBoxModel radiusMethodModel = new EnumModel( boosters, "RadiusMethod", RadiusMethod.choices()); final JComboBox radiusMethodCombo = new JComboBox( radiusMethodModel ); motherPanel.add( radiusMethodCombo, "spanx 3, growx, wrap"); + order.add(radiusMethodCombo); // set radial distance JLabel radiusLabel = new JLabel(trans.get("StageConfig.parallel.radius")); @@ -68,6 +69,7 @@ public class ComponentAssemblyConfig extends RocketComponentConfig { JSpinner radiusSpinner = new JSpinner(radiusModel.getSpinnerModel()); radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner)); motherPanel.add(radiusSpinner , "wmin 65lp, growx 1, align right"); + order.add(((SpinnerEditor) radiusSpinner.getEditor()).getTextField()); // autoRadOffsModel.addEnableComponent(radiusSpinner, false); UnitSelector radiusUnitSelector = new UnitSelector(radiusModel); motherPanel.add(radiusUnitSelector, "growx 1"); @@ -89,6 +91,7 @@ public class ComponentAssemblyConfig extends RocketComponentConfig { JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel()); angleSpinner.setEditor(new SpinnerEditor(angleSpinner)); motherPanel.add(angleSpinner, "wmin 65lp, growx 1"); + order.add(((SpinnerEditor) angleSpinner.getEditor()).getTextField()); UnitSelector angleUnitSelector = new UnitSelector(angleModel); motherPanel.add( angleUnitSelector, "growx 1"); motherPanel.add(new BasicSlider(angleModel.getSliderModel(-Math.PI, Math.PI)), "gapleft para, growx 2, wrap"); @@ -101,6 +104,7 @@ public class ComponentAssemblyConfig extends RocketComponentConfig { JSpinner countSpinner = new JSpinner(countModel.getSpinnerModel()); countSpinner.setEditor(new SpinnerEditor(countSpinner)); motherPanel.add(countSpinner, "wmin 65lp, growx 1, wrap"); + order.add(((SpinnerEditor) countSpinner.getEditor()).getTextField()); // setPositions relative to parent component JLabel positionLabel = new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto")); @@ -109,6 +113,7 @@ public class ComponentAssemblyConfig extends RocketComponentConfig { ComboBoxModel axialPositionMethodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); JComboBox positionMethodCombo = new JComboBox( axialPositionMethodModel ); motherPanel.add(positionMethodCombo, "spanx 3, growx, wrap"); + order.add(positionMethodCombo); // plus motherPanel.add(new JLabel(trans.get("StageConfig.parallel.plus")), "right"); @@ -116,8 +121,8 @@ public class ComponentAssemblyConfig extends RocketComponentConfig { final DoubleModel axialOffsetModel = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH); final JSpinner axialOffsetSpinner = new JSpinner(axialOffsetModel.getSpinnerModel()); axialOffsetSpinner.setEditor(new SpinnerEditor(axialOffsetSpinner)); - motherPanel.add(axialOffsetSpinner, "wmin 65lp, growx 1"); + order.add(((SpinnerEditor) axialOffsetSpinner.getEditor()).getTextField()); positionMethodCombo.addActionListener(new ActionListener() { @Override diff --git a/swing/src/net/sf/openrocket/gui/configdialog/EllipticalFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/EllipticalFinSetConfig.java index db07228b2..add84adfb 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/EllipticalFinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/EllipticalFinSetConfig.java @@ -15,6 +15,7 @@ import javax.swing.SwingConstants; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.IntegerModel; @@ -51,6 +52,7 @@ public class EllipticalFinSetConfig extends FinSetConfig { spin = new JSpinner(im.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx, wrap"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); //// Base rotation @@ -61,6 +63,7 @@ public class EllipticalFinSetConfig extends FinSetConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap"); @@ -78,6 +81,7 @@ public class EllipticalFinSetConfig extends FinSetConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(-FinSet.MAX_CANT_RADIANS, FinSet.MAX_CANT_RADIANS)), @@ -93,6 +97,7 @@ public class EllipticalFinSetConfig extends FinSetConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap"); @@ -106,6 +111,7 @@ public class EllipticalFinSetConfig extends FinSetConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap"); @@ -118,6 +124,7 @@ public class EllipticalFinSetConfig extends FinSetConfig { final EnumModel axialMethodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); final JComboBox axialMethodCombo = new JComboBox( axialMethodModel ); panel.add(axialMethodCombo, "spanx, growx, wrap"); + order.add(axialMethodCombo); //// plus panel.add(new JLabel(trans.get("EllipticalFinSetCfg.plus")), "right"); @@ -126,6 +133,7 @@ public class EllipticalFinSetConfig extends FinSetConfig { spin = new JSpinner(axialOffsetModel.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); axialMethodCombo.addActionListener(new ActionListener() { @Override @@ -157,7 +165,7 @@ public class EllipticalFinSetConfig extends FinSetConfig { JComboBox sectionCombo = new JComboBox( new EnumModel(component, "CrossSection")); panel.add( sectionCombo, "growx, wrap unrel"); - + order.add(sectionCombo); //// Thickness: panel.add(new JLabel(trans.get("EllipticalFinSetCfg.Thickness"))); @@ -167,6 +175,7 @@ public class EllipticalFinSetConfig extends FinSetConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 30lp"); @@ -174,8 +183,9 @@ public class EllipticalFinSetConfig extends FinSetConfig { //// Material - panel.add(materialPanel(Material.Type.BULK), "span, wrap"); - + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel.add(materialPanel, "span, wrap"); + panel.add(filletMaterialPanel(), "span, wrap"); @@ -189,6 +199,11 @@ public class EllipticalFinSetConfig extends FinSetConfig { tabbedPane.insertTab(trans.get("EllipticalFinSetCfg.General"), null, mainPanel, trans.get("EllipticalFinSetCfg.Generalproperties"), 0); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java index 8017c862f..785eb73fa 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java @@ -20,6 +20,7 @@ import javax.swing.SwingUtilities; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.MaterialModel; @@ -135,11 +136,15 @@ public abstract class FinSetConfig extends RocketComponentConfig { }); split.setEnabled(((FinSet) component).getFinCount() > 1); - if (convert == null) + if (convert == null) { addButtons(split); - else + order.add(split); + } + else { addButtons(split, convert); - + order.add(split); + order.add(convert); + } } private JPanel finTabPanel() { @@ -183,6 +188,7 @@ public abstract class FinSetConfig extends RocketComponentConfig { spin = new JSpinner(tabLength.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx 1"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(tabLength), "growx 1"); panel.add(new BasicSlider(tabLength.getSliderModel(DoubleModel.ZERO, length)), @@ -200,6 +206,7 @@ public abstract class FinSetConfig extends RocketComponentConfig { spin = new JSpinner(tabHeightModel.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(tabHeightModel), "growx"); panel.add(new BasicSlider(tabHeightModel.getSliderModel(DoubleModel.ZERO, maxTabHeight)), @@ -216,6 +223,7 @@ public abstract class FinSetConfig extends RocketComponentConfig { spin = new JSpinner(tabOffset.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(tabOffset), "growx"); panel.add(new BasicSlider(tabOffset.getSliderModel(length_2, length2)), "w 100lp, growx 5, wrap"); @@ -230,6 +238,7 @@ public abstract class FinSetConfig extends RocketComponentConfig { JComboBox enumCombo = new JComboBox<>(tabOffsetMethod); panel.add( enumCombo, "spanx 3, growx, wrap para"); + order.add(enumCombo); // Calculate fin tab height, length, and position autoCalc = new SelectColorButton(trans.get("FinSetConfig.but.AutoCalc")); @@ -242,6 +251,7 @@ public abstract class FinSetConfig extends RocketComponentConfig { } }); panel.add(autoCalc, "skip 1, spanx"); + order.add(autoCalc); return panel; } @@ -543,6 +553,8 @@ public abstract class FinSetConfig extends RocketComponentConfig { trans.get("FinsetCfg.ttip.Finfillets2") + trans.get("FinsetCfg.ttip.Finfillets3"); filletPanel.setBorder(BorderFactory.createTitledBorder("Root Fillets")); + + // Fillet Radius: filletPanel.add(new JLabel(trans.get("FinSetCfg.lbl.Filletradius"))); DoubleModel m = new DoubleModel(component, "FilletRadius", UnitGroup.UNITS_LENGTH, 0); @@ -551,13 +563,15 @@ public abstract class FinSetConfig extends RocketComponentConfig { spin.setEditor(new SpinnerEditor(spin)); spin.setToolTipText(tip); filletPanel.add(spin, "growx, w 40"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); UnitSelector us = new UnitSelector(m); filletPanel.add(us, "growx"); us.setToolTipText(tip); BasicSlider bs =new BasicSlider(m.getSliderModel(0, 10)); filletPanel.add(bs, "w 100lp, wrap para"); bs.setToolTipText(tip); - + + // Fillet Material: JLabel label = new JLabel(trans.get("FinSetCfg.lbl.Finfilletmaterial")); label.setToolTipText(tip); //// The component material affects the weight of the component. @@ -569,7 +583,9 @@ public abstract class FinSetConfig extends RocketComponentConfig { //// The component material affects the weight of the component. materialCombo.setToolTipText(trans.get("RocketCompCfg.combo.ttip.componentmaterialaffects")); filletPanel.add( materialCombo, "spanx 4, growx, wrap paragraph"); + order.add(materialCombo); filletPanel.setToolTipText(tip); + return filletPanel; } } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java index b695e5dbf..f3777b3b0 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java @@ -35,6 +35,7 @@ import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.table.AbstractTableModel; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -94,6 +95,11 @@ public class FreeformFinSetConfig extends FinSetConfig { tabbedPane.setSelectedIndex(0); addFinSetButtons(); + + // Apply the custom focus travel policy to this panel + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } @@ -113,6 +119,7 @@ public class FreeformFinSetConfig extends FinSetConfig { JSpinner spin = new JSpinner(finCountModel.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx, wrap"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); } { //// Base rotation @@ -123,6 +130,7 @@ public class FreeformFinSetConfig extends FinSetConfig { JSpinner spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap"); @@ -140,6 +148,7 @@ public class FreeformFinSetConfig extends FinSetConfig { final JSpinner cantAngleSpinner = new JSpinner(cantAngleModel.getSpinnerModel()); cantAngleSpinner.setEditor(new SpinnerEditor(cantAngleSpinner)); panel.add(cantAngleSpinner, "growx"); + order.add(((SpinnerEditor) cantAngleSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(cantAngleModel), "growx"); panel.add(new BasicSlider(cantAngleModel.getSliderModel(-FinSet.MAX_CANT_RADIANS, FinSet.MAX_CANT_RADIANS)), "w 100lp, wrap 40lp"); @@ -154,6 +163,7 @@ public class FreeformFinSetConfig extends FinSetConfig { final EnumModel axialMethodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods); final JComboBox axialMethodCombo = new JComboBox(axialMethodModel); panel.add(axialMethodCombo, "spanx 3, growx, wrap"); + order.add(axialMethodCombo); //// plus panel.add(new JLabel(trans.get("FreeformFinSetCfg.lbl.plus")), "right"); @@ -162,6 +172,7 @@ public class FreeformFinSetConfig extends FinSetConfig { final JSpinner axialOffsetSpinner = new JSpinner(axialOffsetModel.getSpinnerModel()); axialOffsetSpinner.setEditor(new SpinnerEditor(axialOffsetSpinner)); panel.add(axialOffsetSpinner, "growx"); + order.add(((SpinnerEditor) axialOffsetSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(axialOffsetModel), "growx"); panel.add(new BasicSlider(axialOffsetModel.getSliderModel(new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE), new DoubleModel(component.getParent(), "Length"))), "w 100lp, wrap"); @@ -186,6 +197,7 @@ public class FreeformFinSetConfig extends FinSetConfig { panel.add(new JLabel(trans.get("FreeformFinSetCfg.lbl.FincrossSection")), "span, split"); JComboBox sectionCombo = new JComboBox<>(new EnumModel(component, "CrossSection")); panel.add(sectionCombo, "growx, wrap unrel"); + order.add(sectionCombo); //// Thickness: @@ -196,18 +208,21 @@ public class FreeformFinSetConfig extends FinSetConfig { final JSpinner spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 30lp"); } { //// Material - panel.add(materialPanel(Material.Type.BULK), "span, wrap"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel.add(materialPanel, "span, wrap"); + panel.add(filletMaterialPanel(), "span, wrap"); } mainPanel.add(panel, "aligny 20%"); - + return mainPanel; } @@ -288,7 +303,8 @@ public class FreeformFinSetConfig extends FinSetConfig { panel.setLayout(new MigLayout("fill, gap 5!","", "[nogrid, fill, sizegroup display, growprio 200]5![sizegroup text, growprio 5]5![sizegroup buttons, align top, growprio 5]0!")); // first row: main display - panel.add(tablePane, "width 100lp:100lp:, growy"); + panel.add(tablePane, "width 100lp:100lp:, growy"); + order.add(table); panel.add(figurePane, "width 200lp:400lp:, gap unrel, grow, height 100lp:250lp:, wrap"); // row of text directly below figure diff --git a/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java index 3e3ddb3cb..45c984dd5 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java @@ -32,6 +32,7 @@ import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.Resettable; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.components.BasicSlider; @@ -83,6 +84,7 @@ public class InnerTubeConfig extends RocketComponentConfig { spin = new JSpinner(od.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(od), "growx"); panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "wmin 100lp, growx, wrap"); @@ -103,6 +105,7 @@ public class InnerTubeConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "wmin 100lp, growx, wrap"); @@ -124,6 +127,7 @@ public class InnerTubeConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "wmin 100lp, growx, wrap"); @@ -139,13 +143,14 @@ public class InnerTubeConfig extends RocketComponentConfig { spin.setEditor(new SpinnerEditor(spin)); focusElement = spin; panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "wmin 100lp, growx, wrap"); //// Material - panel.add(materialPanel(Material.Type.BULK), - "spanx 4, growx, wrap 15lp"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel.add(materialPanel, "spanx 4, growx, wrap 15lp"); //// Right side of panel ---- @@ -160,6 +165,7 @@ public class InnerTubeConfig extends RocketComponentConfig { JComboBox combo = new JComboBox( new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods )); panel2.add(combo, "spanx 3, growx, wrap"); + order.add(combo); //// plus panel2.add(new JLabel(trans.get("ringcompcfg.plus")), "right"); @@ -169,6 +175,7 @@ public class InnerTubeConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel2.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel2.add(new UnitSelector(m), "growx"); panel2.add(new BasicSlider(m.getSliderModel( @@ -182,7 +189,7 @@ 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, order); tabbedPane.insertTab(trans.get("InnerTubeCfg.tab.Motor"), null, motorConfig, trans.get("InnerTubeCfg.tab.ttip.Motor"), 1); @@ -198,6 +205,11 @@ public class InnerTubeConfig extends RocketComponentConfig { trans.get("InnerTubeCfg.tab.ttip.Radialpos"), 3); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } protected JPanel positionTab() { @@ -217,6 +229,7 @@ public class InnerTubeConfig extends RocketComponentConfig { //// Distance from the rocket centerline spin.setToolTipText(trans.get("ringcompcfg.Distancefrom")); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); BasicSlider bs = new BasicSlider(m.getSliderModel(0, 0.1, 1.0)); @@ -238,6 +251,7 @@ public class InnerTubeConfig extends RocketComponentConfig { //// The radial direction from the rocket centerline spin.setToolTipText(trans.get("ringcompcfg.radialdirectionfrom")); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); bs = new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)); @@ -258,6 +272,7 @@ public class InnerTubeConfig extends RocketComponentConfig { } }); panel.add(button, "spanx, right, wrap para"); + order.add(button); DescriptionArea note = new DescriptionArea(3); @@ -265,7 +280,6 @@ public class InnerTubeConfig extends RocketComponentConfig { note.setText(trans.get("ringcompcfg.note.desc")); panel.add(note, "spanx, growx"); - return panel; } @@ -301,6 +315,7 @@ public class InnerTubeConfig extends RocketComponentConfig { //// The separation of the tubes, 1.0 = touching each other spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep")); subPanel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); BasicSlider bs = new BasicSlider(dm.getSliderModel(0, 1, 4)); //// The separation of the tubes, 1.0 = touching each other @@ -320,6 +335,7 @@ public class InnerTubeConfig extends RocketComponentConfig { //// Rotation angle of the cluster configuration spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation")); subPanel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); subPanel.add(new UnitSelector(dm), "growx"); bs = new BasicSlider(dm.getSliderModel(-Math.PI, 0, Math.PI)); @@ -378,7 +394,7 @@ public class InnerTubeConfig extends RocketComponentConfig { } }); subPanel.add(split, "spanx, split 2, gapright para, sizegroup buttons, right"); - + order.add(split); // Reset button ///// Reset settings @@ -393,14 +409,13 @@ public class InnerTubeConfig extends RocketComponentConfig { } }); subPanel.add(reset, "sizegroup buttons, right"); + order.add(reset); panel.add(subPanel, "grow"); - return panel; } - } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java index 8302641bb..37d93a0fd 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java @@ -10,6 +10,7 @@ import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.components.BasicSlider; @@ -47,6 +48,7 @@ public class LaunchLugConfig extends RocketComponentConfig { spin.setEditor(new SpinnerEditor(spin)); focusElement = spin; panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.02, 0.1)), "w 100lp, wrap para"); @@ -62,6 +64,7 @@ public class LaunchLugConfig extends RocketComponentConfig { spin = new JSpinner(od.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(od), "growx"); panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap rel"); @@ -77,6 +80,7 @@ public class LaunchLugConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "w 100lp, wrap rel"); @@ -91,6 +95,7 @@ public class LaunchLugConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 20lp"); @@ -104,6 +109,7 @@ public class LaunchLugConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI) ), "w 100lp, wrap"); @@ -119,6 +125,7 @@ public class LaunchLugConfig extends RocketComponentConfig { EnumModel positionModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); JComboBox positionCombo = new JComboBox( positionModel ); panel.add(positionCombo, "spanx, growx, wrap"); + order.add(positionCombo); //// plus final DoubleModel mAxOff = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH); @@ -126,6 +133,7 @@ public class LaunchLugConfig extends RocketComponentConfig { spin = new JSpinner(mAxOff.getSpinnerModel()); // Plus quantity input spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(mAxOff), "growx"); // Unity selection panel.add(new BasicSlider(mAxOff.getSliderModel( // Plus quantity slider @@ -142,7 +150,8 @@ public class LaunchLugConfig extends RocketComponentConfig { }); //// Material - panel.add(materialPanel( Material.Type.BULK), "span, wrap"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel.add(materialPanel, "span, wrap"); primary.add(panel, "grow"); @@ -151,6 +160,11 @@ public class LaunchLugConfig extends RocketComponentConfig { tabbedPane.insertTab(trans.get("LaunchLugCfg.tab.General"), null, primary, trans.get("LaunchLugCfg.tab.Generalprop"), 0); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } @Override diff --git a/swing/src/net/sf/openrocket/gui/configdialog/MassComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/MassComponentConfig.java index d5666cc73..5bb30f602 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/MassComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/MassComponentConfig.java @@ -14,6 +14,7 @@ import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.components.BasicSlider; @@ -57,6 +58,7 @@ public class MassComponentConfig extends RocketComponentConfig { MassComponent.MassComponentType.BATTERY})); panel.add(typecombo, "spanx, wrap"); + order.add(typecombo); //// Mass panel.add(new JLabel(trans.get("MassComponentCfg.lbl.Mass"))); @@ -66,11 +68,12 @@ public class MassComponentConfig extends RocketComponentConfig { JSpinner spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.5)), "w 100lp, wrap"); - + /// Approximate Density panel.add(new JLabel(trans.get("MassComponentCfg.lbl.Density"))); m = new DoubleModel(component, "Density", UnitGroup.UNITS_DENSITY_BULK, 0); @@ -78,6 +81,7 @@ public class MassComponentConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(500, 2000, 10000)), "w 100lp, wrap"); @@ -93,6 +97,7 @@ public class MassComponentConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.5)), "w 100lp, wrap"); @@ -108,6 +113,7 @@ public class MassComponentConfig extends RocketComponentConfig { spin = new JSpinner(od.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(od), "growx"); panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap"); @@ -117,6 +123,7 @@ public class MassComponentConfig extends RocketComponentConfig { checkAutoPackedRadius.setText(trans.get("ParachuteCfg.checkbox.AutomaticPacked")); checkAutoPackedRadius.setToolTipText(trans.get("ParachuteCfg.checkbox.AutomaticPacked.ttip")); panel.add(checkAutoPackedRadius, "skip, span 2, wrap"); + order.add(checkAutoPackedRadius); //// Right side @@ -132,6 +139,7 @@ public class MassComponentConfig extends RocketComponentConfig { final EnumModel methodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); final JComboBox methodCombo = new JComboBox( methodModel ); panel2.add(methodCombo, "spanx, growx, wrap"); + order.add(methodCombo); //// plus panel2.add(new JLabel(trans.get("MassComponentCfg.lbl.plus")), "right"); @@ -139,8 +147,8 @@ public class MassComponentConfig extends RocketComponentConfig { m = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH); spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); - focusElement = spin; panel2.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel2.add(new UnitSelector(m), "growx"); panel2.add(new BasicSlider(m.getSliderModel( @@ -156,6 +164,11 @@ public class MassComponentConfig extends RocketComponentConfig { tabbedPane.insertTab(trans.get("MassComponentCfg.tab.Radialpos"), null, positionTab(), trans.get("MassComponentCfg.tab.ttip.Radialpos"), 1); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } @@ -171,6 +184,7 @@ public class MassComponentConfig extends RocketComponentConfig { JSpinner spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); @@ -184,6 +198,7 @@ public class MassComponentConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap"); @@ -199,7 +214,8 @@ public class MassComponentConfig extends RocketComponentConfig { } }); panel.add(button, "spanx, right"); - + order.add(button); + return panel; } } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/MaterialPanel.java b/swing/src/net/sf/openrocket/gui/configdialog/MaterialPanel.java new file mode 100644 index 000000000..cbdeb630a --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/configdialog/MaterialPanel.java @@ -0,0 +1,101 @@ +package net.sf.openrocket.gui.configdialog; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.adaptors.EnumModel; +import net.sf.openrocket.gui.adaptors.MaterialModel; +import net.sf.openrocket.gui.widgets.SelectColorButton; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.material.Material; +import net.sf.openrocket.rocketcomponent.ExternalComponent; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.startup.Application; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Panel for configuring a component's material and finish properties. + */ +public class MaterialPanel extends JPanel { + private static final Translator trans = Application.getTranslator(); + + public MaterialPanel(RocketComponent component, OpenRocketDocument document, + Material.Type type, String materialString, String finishString, + String partName, List order) { + super(new MigLayout("insets 0")); + JLabel label = new JLabel(materialString); + //// The component material affects the weight of the component. + label.setToolTipText(trans.get("RocketCompCfg.lbl.ttip.componentmaterialaffects")); + this.add(label, "spanx 4, wrap rel"); + + JComboBox materialCombo = new JComboBox<>(new MaterialModel(this, component, type, partName)); + //// The component material affects the weight of the component. + materialCombo.setToolTipText(trans.get("RocketCompCfg.combo.ttip.componentmaterialaffects")); + this.add(materialCombo, "spanx 4, growx, wrap paragraph"); + order.add(materialCombo); + + if (component instanceof ExternalComponent) { + label = new JLabel(finishString); + ////The component finish affects the aerodynamic drag of the component.
+ String tip = trans.get("RocketCompCfg.lbl.longA1") + //// The value indicated is the average roughness height of the surface. + + trans.get("RocketCompCfg.lbl.longA2"); + label.setToolTipText(tip); + this.add(label, "spanx 4, wmin 220lp, wrap rel"); + + JComboBox finishCombo = new JComboBox( + new EnumModel(component, "Finish")); + finishCombo.setToolTipText(tip); + this.add(finishCombo, "spanx 4, growx, split"); + order.add(finishCombo); + + //// Set for all + JButton button = new SelectColorButton(trans.get("RocketCompCfg.but.Setforall")); + //// Set this finish for all components of the rocket. + button.setToolTipText(trans.get("RocketCompCfg.but.ttip.Setforall")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ExternalComponent.Finish f = ((ExternalComponent) component).getFinish(); + try { + document.startUndo("Set rocket finish"); + + // Do changes + Iterator iter = component.getRoot().iterator(); + while (iter.hasNext()) { + RocketComponent c = iter.next(); + if (c instanceof ExternalComponent) { + ((ExternalComponent) c).setFinish(f); + } + } + } finally { + document.stopUndo(); + } + } + }); + this.add(button, "wrap paragraph"); + order.add(button); + } + } + + public MaterialPanel(RocketComponent component, OpenRocketDocument document, + Material.Type type, String partName, List order) { + this(component, document, type, trans.get("RocketCompCfg.lbl.Componentmaterial"), + trans.get("RocketCompCfg.lbl.Componentfinish"), partName, order); + } + + public MaterialPanel(RocketComponent component, OpenRocketDocument document, + Material.Type type, List order) { + this(component, document, type, trans.get("RocketCompCfg.lbl.Componentmaterial"), + trans.get("RocketCompCfg.lbl.Componentfinish"), "Material", order); + } +} 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/NoseConeConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/NoseConeConfig.java index 18cd63fac..06e711b85 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/NoseConeConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/NoseConeConfig.java @@ -16,6 +16,7 @@ import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; import net.sf.openrocket.gui.adaptors.BooleanModel; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.TransitionShapeModel; import net.sf.openrocket.gui.components.BasicSlider; @@ -67,6 +68,7 @@ public class NoseConeConfig extends RocketComponentConfig { } }); panel.add(typeBox, "span, wrap rel"); + order.add(typeBox); //// Shape parameter: this.shapeLabel = new JLabel(trans.get("NoseConeCfg.lbl.Shapeparam")); @@ -77,6 +79,7 @@ public class NoseConeConfig extends RocketComponentConfig { this.shapeSpinner = new JSpinner(parameterModel.getSpinnerModel()); shapeSpinner.setEditor(new SpinnerEditor(shapeSpinner)); panel.add(shapeSpinner, "growx"); + order.add(((SpinnerEditor) shapeSpinner.getEditor()).getTextField()); DoubleModel min = new DoubleModel(component, "ShapeParameterMin"); DoubleModel max = new DoubleModel(component, "ShapeParameterMax"); @@ -93,6 +96,7 @@ public class NoseConeConfig extends RocketComponentConfig { JSpinner spin = new JSpinner(lengthModel.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(lengthModel), "growx"); panel.add(new BasicSlider(lengthModel.getSliderModel(0, 0.1, 0.7)), "w 100lp, wrap"); @@ -106,6 +110,7 @@ public class NoseConeConfig extends RocketComponentConfig { final JSpinner radiusSpinner = new JSpinner(aftRadiusModel.getSpinnerModel()); radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner)); panel.add(radiusSpinner, "growx"); + order.add(((SpinnerEditor) radiusSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(aftRadiusModel), "growx"); panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px"); @@ -114,6 +119,7 @@ public class NoseConeConfig extends RocketComponentConfig { //// Automatic checkAutoAftRadius.setText(trans.get("NoseConeCfg.checkbox.Automatic")); panel.add(checkAutoAftRadius, "skip, span 2, wrap"); + order.add(checkAutoAftRadius); updateCheckboxAutoAftRadius(); } @@ -124,6 +130,7 @@ public class NoseConeConfig extends RocketComponentConfig { final JSpinner thicknessSpinner = new JSpinner(thicknessModel.getSpinnerModel()); thicknessSpinner.setEditor(new SpinnerEditor(thicknessSpinner)); panel.add(thicknessSpinner, "growx"); + order.add(((SpinnerEditor) thicknessSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(thicknessModel), "growx"); panel.add(new BasicSlider(thicknessModel.getSliderModel(0, 0.01)), "w 100lp, wrap 0px"); @@ -134,6 +141,7 @@ public class NoseConeConfig extends RocketComponentConfig { filledCheckbox.setText(trans.get("NoseConeCfg.checkbox.Filled")); filledCheckbox.setToolTipText(trans.get("NoseConeCfg.checkbox.Filled.ttip")); panel.add(filledCheckbox, "skip, span 2, wrap"); + order.add(filledCheckbox); } panel.add(new JLabel(""), "growy"); @@ -148,7 +156,8 @@ public class NoseConeConfig extends RocketComponentConfig { //// Material - panel2.add(materialPanel( Material.Type.BULK), "span, wrap"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel2.add(materialPanel, "span, wrap"); panel.add(panel2, "cell 4 0, gapleft paragraph, aligny 0%, spany"); @@ -159,6 +168,11 @@ public class NoseConeConfig extends RocketComponentConfig { tabbedPane.insertTab(trans.get("NoseConeCfg.tab.Shoulder"), null, shoulderTab(), trans.get("NoseConeCfg.tab.ttip.Shoulder"), 1); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java index 1d7325103..74f9f85e6 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java @@ -18,10 +18,7 @@ import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; -import net.sf.openrocket.gui.adaptors.DoubleModel; -import net.sf.openrocket.gui.adaptors.EnumModel; -import net.sf.openrocket.gui.adaptors.IntegerModel; -import net.sf.openrocket.gui.adaptors.MaterialModel; +import net.sf.openrocket.gui.adaptors.*; import net.sf.openrocket.gui.components.BasicSlider; import net.sf.openrocket.gui.components.HtmlLabel; import net.sf.openrocket.gui.components.StyledLabel; @@ -62,6 +59,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { JSpinner spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.4, 1.5)), "w 100lp, wrap"); @@ -87,7 +85,9 @@ public class ParachuteConfig extends RecoveryDeviceConfig { Material.Type.SURFACE)); surfaceMaterialCombo.setToolTipText(trans.get("ParachuteCfg.combo.MaterialModel")); panel.add( surfaceMaterialCombo, "spanx 3, growx, wrap 15lp"); + order.add(surfaceMaterialCombo); + // Drag Coefficient: // CD JLabel label = new HtmlLabel(trans.get("ParachuteCfg.lbl.longA1")); String tip = trans.get("ParachuteCfg.lbl.longB1") + @@ -102,7 +102,8 @@ public class ParachuteConfig extends RecoveryDeviceConfig { spin.setToolTipText(tip); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); - + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); + //// Reset button JButton button = new SelectColorButton(trans.get("ParachuteCfg.but.Reset")); button.setToolTipText(String.format(trans.get("ParachuteCfg.but.ResetCd.ttip"), Parachute.DEFAULT_CD)); @@ -114,6 +115,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { } }); panel.add(button, "spanx, wrap 32lp"); + order.add(button); //// Shroud lines panel.add(new StyledLabel(trans.get("ParachuteCfg.lbl.Shroudlines"), Style.BOLD), "wrap unrel"); @@ -125,6 +127,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { spin = new JSpinner(im.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx, wrap"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); //// Line length: panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Linelength"))); @@ -134,6 +137,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.4, 1.5)), "w 100lp, wrap"); @@ -143,6 +147,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { JComboBox shroudMaterialCombo = new JComboBox(new MaterialModel(panel, component, Material.Type.LINE, "LineMaterial")); panel.add( shroudMaterialCombo, "spanx 3, growx, wrap 15lp"); + order.add(shroudMaterialCombo); // Right side @@ -159,6 +164,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); JComboBox positionCombo = new JComboBox( methodModel ); panel.add( positionCombo, "spanx, growx, wrap"); + order.add(positionCombo); //// plus panel.add(new JLabel(trans.get("ParachuteCfg.lbl.plus")), "right"); @@ -168,6 +174,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { spin.setEditor(new SpinnerEditor(spin)); focusElement = spin; panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel( @@ -184,6 +191,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.5)), "w 100lp, wrap"); @@ -199,6 +207,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { spin = new JSpinner(od.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(od), "growx"); panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap"); @@ -208,6 +217,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { checkAutoPackedRadius.setText(trans.get("ParachuteCfg.checkbox.AutomaticPacked")); checkAutoPackedRadius.setToolTipText(trans.get("ParachuteCfg.checkbox.AutomaticPacked.ttip")); panel.add(checkAutoPackedRadius, "skip, span 2, wrap 5lp"); + order.add(checkAutoPackedRadius); //// Deployment panel.add(new StyledLabel(trans.get("ParachuteCfg.lbl.Deployment"), Style.BOLD), "wrap unrel"); @@ -232,6 +242,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { } }); panel.add(eventCombo, "spanx 3, growx, wrap"); + order.add(eventCombo); // ... and delay //// plus @@ -241,6 +252,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin, 3)); panel.add(spin, "spanx, split"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); //// seconds panel.add(new JLabel(trans.get("ParachuteCfg.lbl.seconds")), "wrap paragraph"); @@ -256,6 +268,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { spin.setEditor(new SpinnerEditor(spin)); altitudeComponents.add(spin); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); UnitSelector unit = new UnitSelector(m); altitudeComponents.add(unit); panel.add(unit, "growx"); @@ -275,6 +288,11 @@ public class ParachuteConfig extends RecoveryDeviceConfig { tabbedPane.insertTab(trans.get("ParachuteCfg.tab.Radialpos"), null, positionTab(), trans.get("ParachuteCfg.tab.ttip.Radialpos"), 1); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } @@ -290,6 +308,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { JSpinner spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); @@ -303,6 +322,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap"); @@ -319,7 +339,8 @@ public class ParachuteConfig extends RecoveryDeviceConfig { } }); panel.add(button, "spanx, right"); - + order.add(button); + return panel; } } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java index be4803c42..900b09496 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java @@ -7,9 +7,9 @@ import javax.swing.JPanel; import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.database.Databases; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.components.BasicSlider; @@ -33,7 +33,11 @@ public class RailButtonConfig extends RocketComponentConfig { //// General and General properties tabbedPane.insertTab( trans.get("RailBtnCfg.tab.General"), null, buttonTab( (RailButton)component ), trans.get("RailBtnCfg.tab.GeneralProp"), 0); tabbedPane.setSelectedIndex(0); - + + // Apply the custom focus travel policy to this panel + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } private JPanel buttonTab( final RailButton rbc ){ @@ -49,6 +53,7 @@ public class RailButtonConfig extends RocketComponentConfig { JSpinner ODSpinner = new JSpinner( ODModel.getSpinnerModel()); ODSpinner.setEditor(new SpinnerEditor(ODSpinner)); panel.add(ODSpinner, "growx"); + order.add(((SpinnerEditor) ODSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(ODModel), "growx"); panel.add(new BasicSlider(ODModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap"); } @@ -58,6 +63,7 @@ public class RailButtonConfig extends RocketComponentConfig { JSpinner IDSpinner = new JSpinner(IDModel.getSpinnerModel()); IDSpinner.setEditor(new SpinnerEditor(IDSpinner)); panel.add(IDSpinner, "growx"); + order.add(((SpinnerEditor) IDSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(IDModel), "growx"); panel.add(new BasicSlider(IDModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para"); } @@ -67,6 +73,7 @@ public class RailButtonConfig extends RocketComponentConfig { JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel()); heightSpinner.setEditor(new SpinnerEditor(heightSpinner)); panel.add(heightSpinner, "growx"); + order.add(((SpinnerEditor) heightSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(heightModel), "growx"); panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap"); } @@ -76,6 +83,7 @@ public class RailButtonConfig extends RocketComponentConfig { JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel()); heightSpinner.setEditor(new SpinnerEditor(heightSpinner)); panel.add(heightSpinner, "growx"); + order.add(((SpinnerEditor) heightSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(heightModel), "growx"); panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap"); } @@ -85,6 +93,7 @@ public class RailButtonConfig extends RocketComponentConfig { JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel()); heightSpinner.setEditor(new SpinnerEditor(heightSpinner)); panel.add(heightSpinner, "growx"); + order.add(((SpinnerEditor) heightSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(heightModel), "growx"); panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para"); } @@ -95,6 +104,7 @@ public class RailButtonConfig extends RocketComponentConfig { JSpinner angleSpinner = new JSpinner( angleModel.getSpinnerModel()); angleSpinner.setEditor(new SpinnerEditor(angleSpinner)); panel.add(angleSpinner, "growx"); + order.add(((SpinnerEditor) angleSpinner.getEditor()).getTextField()); panel.add(new UnitSelector( angleModel), "growx"); panel.add(new BasicSlider( angleModel.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap"); } @@ -108,6 +118,7 @@ public class RailButtonConfig extends RocketComponentConfig { final EnumModel methodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); JComboBox relToCombo = new JComboBox( methodModel ); panel.add( relToCombo, "spanx, growx, wrap"); + order.add(relToCombo); } { //// plus @@ -117,6 +128,7 @@ public class RailButtonConfig extends RocketComponentConfig { offsetSpinner.setEditor(new SpinnerEditor(offsetSpinner)); focusElement = offsetSpinner; panel.add(offsetSpinner, "growx"); + order.add(((SpinnerEditor) offsetSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(offsetModel), "growx"); panel.add(new BasicSlider(offsetModel.getSliderModel( new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE), @@ -128,10 +140,11 @@ public class RailButtonConfig extends RocketComponentConfig { panel.add(instanceablePanel(rbc), "span, wrap"); //// Material - panel.add(materialPanel(Material.Type.BULK),"span, wrap"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel.add(materialPanel,"span, wrap"); primary.add(panel, "grow"); - + return primary; } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java index 7e5837f9f..da346f88a 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java @@ -11,6 +11,7 @@ import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.components.BasicSlider; @@ -33,7 +34,7 @@ public class RingComponentConfig extends RocketComponentConfig { super(d, component, parent); } - + protected JPanel generalTab(String outer, String inner, String thickness, String length) { JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", "")); DoubleModel m; @@ -52,6 +53,7 @@ public class RingComponentConfig extends RocketComponentConfig { spin = new JSpinner(od.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(od), "growx"); panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap"); @@ -62,6 +64,7 @@ public class RingComponentConfig extends RocketComponentConfig { check.setText(trans.get("ringcompcfg.Automatic")); check.setToolTipText(trans.get("ringcompcfg.AutomaticOuter.ttip")); panel.add(check, "skip, span 2, wrap"); + order.add(check); } } @@ -76,6 +79,7 @@ public class RingComponentConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); if (od == null) @@ -90,6 +94,7 @@ public class RingComponentConfig extends RocketComponentConfig { check.setText(trans.get("ringcompcfg.Automatic")); check.setToolTipText(trans.get("ringcompcfg.AutomaticInner.ttip")); panel.add(check, "skip, span 2, wrap"); + order.add(check); } } @@ -104,6 +109,7 @@ public class RingComponentConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap"); @@ -123,6 +129,7 @@ public class RingComponentConfig extends RocketComponentConfig { focusElement = spin; } panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); @@ -137,6 +144,7 @@ public class RingComponentConfig extends RocketComponentConfig { final EnumModel methodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); final JComboBox positionCombo = new JComboBox( methodModel ); panel.add( positionCombo, "spanx 3, growx, wrap"); + order.add(positionCombo); //// plus panel.add(new JLabel(trans.get("ringcompcfg.plus")), "right"); @@ -149,6 +157,7 @@ public class RingComponentConfig extends RocketComponentConfig { focusElement = spin; } panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel( @@ -158,16 +167,16 @@ public class RingComponentConfig extends RocketComponentConfig { //// Material - JPanel sub = materialPanel( Material.Type.BULK); - + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + if (component instanceof EngineBlock) { final DescriptionArea desc = new DescriptionArea(6); //// An engine block stops the motor from moving forwards in the motor mount tube.

In order to add a motor, create a body tube or inner tube and mark it as a motor mount in the Motor tab. desc.setText(trans.get("ringcompcfg.EngineBlock.desc")); - sub.add(desc, "width 1px, growx, wrap"); + materialPanel.add(desc, "width 1px, growx, wrap"); } - panel.add(sub, "cell 4 0, gapleft paragraph, aligny 0%, spany"); - + panel.add(materialPanel, "cell 4 0, gapleft paragraph, aligny 0%, spany"); + return panel; } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java index e0af7f493..cb856eaf0 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java @@ -23,6 +23,8 @@ import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.database.ComponentPresetDatabase; @@ -30,9 +32,7 @@ import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.adaptors.DoubleModel; -import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.IntegerModel; -import net.sf.openrocket.gui.adaptors.MaterialModel; import net.sf.openrocket.gui.adaptors.PresetModel; import net.sf.openrocket.gui.components.BasicSlider; import net.sf.openrocket.gui.components.StyledLabel; @@ -42,10 +42,8 @@ import net.sf.openrocket.gui.dialogs.preset.ComponentPresetChooserDialog; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.widgets.SelectColorButton; import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.material.Material; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.rocketcomponent.*; -import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish; import net.sf.openrocket.rocketcomponent.position.AxialMethod; import net.sf.openrocket.startup.Application; import net.sf.openrocket.unit.UnitGroup; @@ -59,8 +57,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; @@ -71,6 +71,7 @@ public class RocketComponentConfig extends JPanel { private final TextFieldListener textFieldListener; private JPanel buttonPanel; + protected JButton closeButton; private AppearancePanel appearancePanel = null; private JLabel infoLabel; @@ -84,6 +85,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; @@ -114,6 +116,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. @@ -123,6 +126,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")); @@ -133,17 +137,25 @@ public class RocketComponentConfig extends JPanel { } }); this.add(selectPreset); + order.add(selectPreset); } tabbedPane = new JTabbedPane(); this.add(tabbedPane, "newline, span, growx, growy 100, wrap"); + order.add(tabbedPane); + tabbedPane.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + tabbedPane.requestFocusInWindow(); + } + }); //// Override and Mass and CG override options tabbedPane.addTab(trans.get("RocketCompCfg.tab.Override"), null, overrideTab(), 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")); } @@ -180,7 +192,7 @@ public class RocketComponentConfig extends JPanel { } //// Close button - JButton closeButton = new SelectColorButton(trans.get("dlg.but.close")); + this.closeButton = new SelectColorButton(trans.get("dlg.but.close")); closeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { @@ -277,79 +289,6 @@ public class RocketComponentConfig extends JPanel { appearancePanel.clearConfigListeners(); } } - - protected JPanel materialPanel(Material.Type type) { - ////Component material: and Component finish: - return materialPanel(type, - trans.get("RocketCompCfg.lbl.Componentmaterial"), - trans.get("RocketCompCfg.lbl.Componentfinish"), - "Material"); - } - - protected JPanel materialPanel(Material.Type type, String partName){ - return materialPanel(type, trans.get("RocketCompCfg.lbl.Componentmaterial"), - trans.get("RocketCompCfg.lbl.Componentfinish"), partName); - } - - protected JPanel materialPanel(Material.Type type, - String materialString, - String finishString, - String partName) { - - JPanel subPanel = new JPanel(new MigLayout("insets 0")); - JLabel label = new JLabel(materialString); - //// The component material affects the weight of the component. - label.setToolTipText(trans.get("RocketCompCfg.lbl.ttip.componentmaterialaffects")); - subPanel.add(label, "spanx 4, wrap rel"); - - JComboBox materialCombo = new JComboBox(new MaterialModel(subPanel, component, type, partName)); - //// The component material affects the weight of the component. - materialCombo.setToolTipText(trans.get("RocketCompCfg.combo.ttip.componentmaterialaffects")); - subPanel.add(materialCombo, "spanx 4, growx, wrap paragraph"); - - - if (component instanceof ExternalComponent) { - label = new JLabel(finishString); - ////The component finish affects the aerodynamic drag of the component.
- String tip = trans.get("RocketCompCfg.lbl.longA1") - //// The value indicated is the average roughness height of the surface. - + trans.get("RocketCompCfg.lbl.longA2"); - label.setToolTipText(tip); - subPanel.add(label, "spanx 4, wmin 220lp, wrap rel"); - - JComboBox finishCombo = new JComboBox( - new EnumModel(component, "Finish")); - finishCombo.setToolTipText(tip); - subPanel.add( finishCombo, "spanx 4, growx, split"); - - //// Set for all - JButton button = new SelectColorButton(trans.get("RocketCompCfg.but.Setforall")); - //// Set this finish for all components of the rocket. - button.setToolTipText(trans.get("RocketCompCfg.but.ttip.Setforall")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Finish f = ((ExternalComponent) component).getFinish(); - try { - document.startUndo("Set rocket finish"); - - // Do changes - Iterator iter = component.getRoot().iterator(); - while (iter.hasNext()) { - RocketComponent c = iter.next(); - if (c instanceof ExternalComponent) { - ((ExternalComponent) c).setFinish(f); - } - } - } finally { - document.stopUndo(); - } - } - }); - subPanel.add(button, "wrap paragraph"); - } - return subPanel; - } public int getSelectedTabIndex() { return tabbedPane.getSelectedIndex(); @@ -389,6 +328,7 @@ public class RocketComponentConfig extends JPanel { JSpinner countSpinner = new JSpinner( countModel.getSpinnerModel()); countSpinner.setEditor(new SpinnerEditor(countSpinner)); panel.add(countSpinner, "w 100lp, wrap rel"); + order.add(((SpinnerEditor) countSpinner.getEditor()).getTextField()); } { // Instance separation @@ -397,6 +337,7 @@ public class RocketComponentConfig extends JPanel { JSpinner separationSpinner = new JSpinner( separationModel.getSpinnerModel()); separationSpinner.setEditor(new SpinnerEditor(separationSpinner)); panel.add(separationSpinner, "growx"); + order.add(((SpinnerEditor) separationSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(separationModel), "growx"); double maxSeparationDistance = 0.1; if (component.getParent() != null && component.getParent().getLength() > 0) { @@ -410,8 +351,8 @@ public class RocketComponentConfig extends JPanel { private JPanel overrideTab() { JPanel panel = new JPanel(new MigLayout("align 50% 20%, fillx, gap rel unrel", "[][65lp::][30lp::][]", "")); - //// Override the mass or center of gravity of the - + //// Override the mass, center of gravity, or drag coeficient of the component + JCheckBox check; BooleanModel bm; UnitSelector us; @@ -425,6 +366,7 @@ public class RocketComponentConfig extends JPanel { check.setText(trans.get("RocketCompCfg.checkbox.Overridemass")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.Overridemass.ttip")); panel.add(check, "growx 1, gapright 20lp"); + order.add(check); DoubleModel m = new DoubleModel(component, "OverrideMass", UnitGroup.UNITS_MASS, 0); @@ -432,6 +374,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); @@ -451,6 +394,7 @@ public class RocketComponentConfig extends JPanel { check.setText(trans.get("RocketCompCfg.checkbox.Overridecenterofgrav")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.Overridecenterofgrav.ttip")); panel.add(check, "growx 1, gapright 20lp"); + order.add(check); m = new DoubleModel(component, "OverrideCGX", UnitGroup.UNITS_LENGTH, 0); // Calculate suitable length for slider @@ -488,6 +432,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); @@ -501,14 +446,14 @@ public class RocketComponentConfig extends JPanel { // END OVERRIDE CG --------------------------------------------------- - // BEGIN OVERRIDE CD --------------------------------------------------- - + // BEGIN OVERRIDE CD ------------------------------------------ bm = new BooleanModel(component, "CDOverridden"); check = new JCheckBox(bm); //// Override coefficient of drag: check.setText(trans.get("RocketCompCfg.checkbox.SetDragCoeff")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.SetDragCoeff.ttip")); panel.add(check, "growx 1, gapright 20lp"); + order.add(check); m = new DoubleModel(component, "OverrideCD", UnitGroup.UNITS_COEFFICIENT, 0); spin = new JSpinner(m.getSpinnerModel()); @@ -516,6 +461,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)); @@ -562,6 +508,7 @@ public class RocketComponentConfig extends JPanel { commentTextArea.addFocusListener(textFieldListener); panel.add(new JScrollPane(commentTextArea), "grow"); + order.add(commentTextArea); return panel; } @@ -596,6 +543,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"); @@ -609,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(0, 0.02, 0.2)), "w 100lp, wrap"); @@ -623,6 +572,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"); @@ -635,6 +585,7 @@ public class RocketComponentConfig extends JPanel { check.setText(trans.get("RocketCompCfg.checkbox.Endcapped")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.Endcapped.ttip")); sub.add(check, "spanx"); + order.add(check); panel.add(sub); @@ -662,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(m0, m2)), "w 100lp, wrap"); @@ -675,6 +627,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"); @@ -689,6 +642,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"); @@ -701,6 +655,7 @@ public class RocketComponentConfig extends JPanel { check.setText(trans.get("RocketCompCfg.checkbox.Endcapped")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.Endcapped.ttip")); sub.add(check, "spanx"); + order.add(check); panel.add(sub); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ShockCordConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ShockCordConfig.java index 29f574c2a..40222576f 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/ShockCordConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/ShockCordConfig.java @@ -6,6 +6,7 @@ import javax.swing.*; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.components.BasicSlider; @@ -50,13 +51,16 @@ public class ShockCordConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 1, 10)), "w 100lp, wrap"); // Material //// Shock cord material: - panel.add(materialPanel(Material.Type.LINE, trans.get("ShockCordCfg.lbl.Shockcordmaterial"), null, "Material"), "spanx 4, wrap"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.LINE, + trans.get("ShockCordCfg.lbl.Shockcordmaterial"), null, "Material", order); + panel.add(materialPanel, "spanx 4, wrap"); @@ -73,6 +77,7 @@ public class ShockCordConfig extends RocketComponentConfig { final EnumModel methodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); final JComboBox combo = new JComboBox( methodModel ); panel2.add(combo, "spanx, growx, wrap"); + order.add(combo); //// plus panel2.add(new JLabel(trans.get("ShockCordCfg.lbl.plus")), "right"); @@ -82,6 +87,7 @@ public class ShockCordConfig extends RocketComponentConfig { spin.setEditor(new SpinnerEditor(spin)); focusElement = spin; panel2.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel2.add(new UnitSelector(m), "growx"); panel2.add(new BasicSlider(m.getSliderModel( @@ -99,6 +105,7 @@ public class ShockCordConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel2.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel2.add(new UnitSelector(m), "growx"); panel2.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.5)), "w 100lp, wrap"); @@ -114,6 +121,7 @@ public class ShockCordConfig extends RocketComponentConfig { spin = new JSpinner(od.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel2.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel2.add(new UnitSelector(od), "growx"); panel2.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap"); @@ -123,6 +131,7 @@ public class ShockCordConfig extends RocketComponentConfig { checkAutoPackedRadius.setText(trans.get("ParachuteCfg.checkbox.AutomaticPacked")); checkAutoPackedRadius.setToolTipText(trans.get("ParachuteCfg.checkbox.AutomaticPacked.ttip")); panel2.add(checkAutoPackedRadius, "skip, span 2, wrap"); + order.add(checkAutoPackedRadius); //// General and General properties tabbedPane.insertTab(trans.get("ShockCordCfg.tab.General"), null, panel, @@ -131,6 +140,11 @@ public class ShockCordConfig extends RocketComponentConfig { tabbedPane.insertTab(trans.get("ShockCordCfg.tab.Radialpos"), null, positionTab(), trans.get("ShockCordCfg.tab.ttip.Radialpos"), 1); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } // TODO: LOW: there is a lot of duplicate code here with other mass components... (e.g. in MassComponentConfig or ParachuteConfig) @@ -146,6 +160,7 @@ public class ShockCordConfig extends RocketComponentConfig { JSpinner spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); @@ -159,6 +174,7 @@ public class ShockCordConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap"); @@ -174,6 +190,7 @@ public class ShockCordConfig extends RocketComponentConfig { } }); panel.add(button, "spanx, right"); + order.add(button); return panel; } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java index 46d0d3e30..4545660c9 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java @@ -5,6 +5,7 @@ import javax.swing.JDialog; import javax.swing.JPanel; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; @@ -28,6 +29,11 @@ public class SleeveConfig extends RingComponentConfig { tabbedPane.insertTab(trans.get("SleeveCfg.tab.General"), null, tab, trans.get("SleeveCfg.tab.Generalproperties"), 0); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this panel + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } } \ No newline at end of file diff --git a/swing/src/net/sf/openrocket/gui/configdialog/StreamerConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/StreamerConfig.java index c2016a9f2..e05cc0f6f 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/StreamerConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/StreamerConfig.java @@ -17,6 +17,7 @@ import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.MaterialModel; @@ -59,6 +60,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { JSpinner spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.6, 1.5)), "w 100lp, wrap"); @@ -70,6 +72,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.2)), "w 100lp, wrap 10lp"); @@ -81,6 +84,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.04, 0.25)), "w 100lp, wrap"); @@ -92,6 +96,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); // panel.add(new UnitSelector(m),"growx"); panel.add(new BasicSlider(m.getSliderModel(2, 15)), "skip, w 100lp, wrap 10lp"); @@ -103,6 +108,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { //// The component material affects the weight of the component. streamerMaterialCombo.setToolTipText(trans.get("StreamerCfg.combo.ttip.MaterialModel")); panel.add(streamerMaterialCombo, "spanx 3, growx, wrap 15lp"); + order.add(streamerMaterialCombo); // CD //// Drag coefficient CD: @@ -120,12 +126,14 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin.setToolTipText(tip); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); JCheckBox check = new JCheckBox(m.getAutomaticAction()); //// Automatic check.setText(trans.get("StreamerCfg.lbl.AutomaticCd")); check.setToolTipText(trans.get("StreamerCfg.lbl.AutomaticCd.ttip")); panel.add(check, "skip, span, wrap"); + order.add(check); //// The drag coefficient is relative to the area of the streamer. panel.add(new StyledLabel(trans.get("StreamerCfg.lbl.longC1"), @@ -145,6 +153,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { final EnumModel methodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); final JComboBox positionCombo = new JComboBox( methodModel ); panel.add( positionCombo, "spanx, growx, wrap"); + order.add(positionCombo); //// plus panel.add(new JLabel(trans.get("StreamerCfg.lbl.plus")), "right"); @@ -154,6 +163,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin.setEditor(new SpinnerEditor(spin)); focusElement = spin; panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel( @@ -170,6 +180,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.5)), "w 100lp, wrap"); @@ -185,6 +196,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin = new JSpinner(od.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(od), "growx"); panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap"); @@ -194,6 +206,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { checkAutoPackedRadius.setText(trans.get("ParachuteCfg.checkbox.AutomaticPacked")); checkAutoPackedRadius.setToolTipText(trans.get("ParachuteCfg.checkbox.AutomaticPacked.ttip")); panel.add(checkAutoPackedRadius, "skip, span 2, wrap 5lp"); + order.add(checkAutoPackedRadius); //// Deployment @@ -215,6 +228,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { } }); panel.add( eventCombo, "spanx 3, growx, wrap"); + order.add(eventCombo); // ... and delay //// plus @@ -224,6 +238,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin, 3)); panel.add(spin, "spanx, split"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); //// seconds panel.add(new JLabel(trans.get("StreamerCfg.lbl.seconds")), "wrap paragraph"); @@ -239,6 +254,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin.setEditor(new SpinnerEditor(spin)); altitudeComponents.add(spin); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); UnitSelector unit = new UnitSelector(m); altitudeComponents.add(unit); panel.add(unit, "growx"); @@ -259,6 +275,11 @@ public class StreamerConfig extends RecoveryDeviceConfig { tabbedPane.insertTab(trans.get("StreamerCfg.tab.Radialpos"), null, positionTab(), trans.get("StreamerCfg.tab.ttip.Radialpos"), 1); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } @@ -277,6 +298,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { JSpinner spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); @@ -289,6 +311,7 @@ public class StreamerConfig extends RecoveryDeviceConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap"); @@ -304,7 +327,8 @@ public class StreamerConfig extends RecoveryDeviceConfig { } }); panel.add(button, "spanx, right"); - + order.add(button); + return panel; } } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java index 5689953f5..b204435a3 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java @@ -5,6 +5,7 @@ import javax.swing.JDialog; import javax.swing.JPanel; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; @@ -30,6 +31,11 @@ public class ThicknessRingComponentConfig extends RingComponentConfig { tabbedPane.insertTab(trans.get("ThicknessRingCompCfg.tab.General"), null, tab, trans.get("ThicknessRingCompCfg.tab.Generalprop"), 0); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this panel + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } } \ No newline at end of file diff --git a/swing/src/net/sf/openrocket/gui/configdialog/TransitionConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/TransitionConfig.java index b5b4c72cc..44e1be699 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/TransitionConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/TransitionConfig.java @@ -15,6 +15,7 @@ import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; import net.sf.openrocket.gui.adaptors.BooleanModel; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.TransitionShapeModel; import net.sf.openrocket.gui.components.BasicSlider; @@ -69,12 +70,14 @@ public class TransitionConfig extends RocketComponentConfig { } }); panel.add(typeBox, "span 3, split 2"); + order.add(typeBox); {//// Clipped final JCheckBox checkbox = new JCheckBox(new BooleanModel(component, "Clipped")); checkbox.setText(trans.get("TransitionCfg.checkbox.Clipped")); checkbox.setToolTipText(trans.get("TransitionCfg.checkbox.Clipped.ttip")); panel.add(checkbox, "wrap"); + order.add(checkbox); //// Shape parameter: this.shapeLabel = new JLabel(trans.get("TransitionCfg.lbl.Shapeparam")); @@ -87,6 +90,7 @@ public class TransitionConfig extends RocketComponentConfig { this.shapeSpinner = new JSpinner(shapeModel.getSpinnerModel()); shapeSpinner.setEditor(new SpinnerEditor(shapeSpinner)); panel.add(shapeSpinner, "growx"); + order.add(((SpinnerEditor) shapeSpinner.getEditor()).getTextField()); DoubleModel min = new DoubleModel(component, "ShapeParameterMin"); DoubleModel max = new DoubleModel(component, "ShapeParameterMax"); @@ -105,6 +109,7 @@ public class TransitionConfig extends RocketComponentConfig { final JSpinner lengthSpinner = new JSpinner(lengthModel.getSpinnerModel()); lengthSpinner.setEditor(new SpinnerEditor(lengthSpinner)); panel.add(lengthSpinner, "growx"); + order.add(((SpinnerEditor) lengthSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(lengthModel), "growx"); panel.add(new BasicSlider(lengthModel.getSliderModel(0, 0.05, 0.3)), "w 100lp, wrap"); @@ -119,6 +124,7 @@ public class TransitionConfig extends RocketComponentConfig { final JSpinner foreRadiusSpinner = new JSpinner(foreRadiusModel.getSpinnerModel()); foreRadiusSpinner.setEditor(new SpinnerEditor(foreRadiusSpinner)); panel.add(foreRadiusSpinner, "growx"); + order.add(((SpinnerEditor) foreRadiusSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(foreRadiusModel), "growx"); panel.add(new BasicSlider(foreRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px"); @@ -127,6 +133,7 @@ public class TransitionConfig extends RocketComponentConfig { //// Automatic checkAutoForeRadius.setText(trans.get("TransitionCfg.checkbox.Automatic")); panel.add(checkAutoForeRadius, "skip, span 2, wrap"); + order.add(checkAutoForeRadius); updateCheckboxAutoForeRadius(); } @@ -139,6 +146,7 @@ public class TransitionConfig extends RocketComponentConfig { final JSpinner aftRadiusSpinner = new JSpinner(aftRadiusModel .getSpinnerModel()); aftRadiusSpinner.setEditor(new SpinnerEditor(aftRadiusSpinner)); panel.add(aftRadiusSpinner, "growx"); + order.add(((SpinnerEditor) aftRadiusSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(aftRadiusModel), "growx"); panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px"); @@ -147,6 +155,7 @@ public class TransitionConfig extends RocketComponentConfig { //// Automatic checkAutoAftRadius.setText(trans.get("TransitionCfg.checkbox.Automatic")); panel.add(checkAutoAftRadius, "skip, span 2, wrap"); + order.add(checkAutoAftRadius); updateCheckboxAutoAftRadius(); } @@ -158,6 +167,7 @@ public class TransitionConfig extends RocketComponentConfig { final JSpinner thicknessSpinner = new JSpinner(thicknessModel.getSpinnerModel()); thicknessSpinner.setEditor(new SpinnerEditor(thicknessSpinner)); panel.add(thicknessSpinner, "growx"); + order.add(((SpinnerEditor) thicknessSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(thicknessModel), "growx"); panel.add(new BasicSlider(thicknessModel.getSliderModel(0, 0.01)), "w 100lp, wrap 0px"); @@ -168,6 +178,7 @@ public class TransitionConfig extends RocketComponentConfig { thicknessCheckbox.setText(trans.get("TransitionCfg.checkbox.Filled")); thicknessCheckbox.setToolTipText(trans.get("TransitionCfg.checkbox.Filled.ttip")); panel.add(thicknessCheckbox, "skip, span 2, wrap"); + order.add(thicknessCheckbox); } //// Description @@ -180,7 +191,8 @@ public class TransitionConfig extends RocketComponentConfig { //// Material - panel2.add(materialPanel(Material.Type.BULK), "span, wrap"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel2.add(materialPanel, "span, wrap"); panel.add(panel2, "cell 4 0, gapleft paragraph, aligny 0%, spany"); //// General and General properties @@ -190,6 +202,11 @@ public class TransitionConfig extends RocketComponentConfig { tabbedPane.insertTab(trans.get("TransitionCfg.tab.Shoulder"), null, shoulderTab(), trans.get("TransitionCfg.tab.Shoulderproperties"), 1); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/TrapezoidFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/TrapezoidFinSetConfig.java index 208cd2aac..df54e7f2f 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/TrapezoidFinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/TrapezoidFinSetConfig.java @@ -15,6 +15,7 @@ import javax.swing.SwingConstants; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.IntegerModel; @@ -55,6 +56,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { //// The number of fins in the fin set. finCountSpinner.setToolTipText(trans.get("TrapezoidFinSetCfg.lbl.ttip.Nbroffins")); panel.add(finCountSpinner, "growx, wrap"); + order.add(((SpinnerEditor) finCountSpinner.getEditor()).getTextField()); { /// Base rotation @@ -68,6 +70,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { final JSpinner baseRotationSpinner = new JSpinner(baseRotationModel.getSpinnerModel()); baseRotationSpinner.setEditor(new SpinnerEditor(baseRotationSpinner)); panel.add(baseRotationSpinner, "growx"); + order.add(((SpinnerEditor) baseRotationSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(baseRotationModel), "growx"); panel.add(new BasicSlider(baseRotationModel.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap"); @@ -84,6 +87,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { final JSpinner cantSpinner = new JSpinner(cantModel.getSpinnerModel()); cantSpinner.setEditor(new SpinnerEditor(cantSpinner)); panel.add(cantSpinner, "growx"); + order.add(((SpinnerEditor) cantSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(cantModel), "growx"); panel.add(new BasicSlider(cantModel.getSliderModel(-FinSet.MAX_CANT_RADIANS, FinSet.MAX_CANT_RADIANS)), @@ -98,6 +102,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { final JSpinner rootChordSpinner = new JSpinner(rootChordModel.getSpinnerModel()); rootChordSpinner.setEditor(new SpinnerEditor(rootChordSpinner)); panel.add(rootChordSpinner, "growx"); + order.add(((SpinnerEditor) rootChordSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(rootChordModel), "growx"); panel.add(new BasicSlider(rootChordModel.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap"); @@ -111,6 +116,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { final JSpinner tipChordSpinner = new JSpinner(tipChordModel.getSpinnerModel()); tipChordSpinner.setEditor(new SpinnerEditor(tipChordSpinner)); panel.add(tipChordSpinner, "growx"); + order.add(((SpinnerEditor) tipChordSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(tipChordModel), "growx"); panel.add(new BasicSlider(tipChordModel.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap"); @@ -124,6 +130,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { final JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel()); heightSpinner.setEditor(new SpinnerEditor(heightSpinner)); panel.add(heightSpinner, "growx"); + order.add(((SpinnerEditor) heightSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(heightModel), "growx"); panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap"); @@ -137,6 +144,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { final JSpinner sweepDistanceSpinner = new JSpinner(sweepDistanceModel.getSpinnerModel()); sweepDistanceSpinner.setEditor(new SpinnerEditor(sweepDistanceSpinner)); panel.add(sweepDistanceSpinner, "growx"); + order.add(((SpinnerEditor) sweepDistanceSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(sweepDistanceModel), "growx"); @@ -156,6 +164,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { final JSpinner sweepAngleSpinner = new JSpinner(sweepAngleModel.getSpinnerModel()); sweepAngleSpinner.setEditor(new SpinnerEditor(sweepAngleSpinner)); panel.add(sweepAngleSpinner, "growx"); + order.add(((SpinnerEditor) sweepAngleSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(sweepAngleModel), "growx"); panel.add(new BasicSlider(sweepAngleModel.getSliderModel(-Math.PI / 4, Math.PI / 4)), @@ -168,6 +177,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { final EnumModel axialMethodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); final JComboBox axialMethodCombo = new JComboBox( axialMethodModel ); panel.add(axialMethodCombo, "spanx, growx, wrap"); + order.add(axialMethodCombo); //// plus panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.plus")), "right"); @@ -177,6 +187,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { axialOffsetSpinner.setEditor(new SpinnerEditor(axialOffsetSpinner)); panel.add(axialOffsetSpinner, "growx"); + order.add(((SpinnerEditor) axialOffsetSpinner.getEditor()).getTextField()); axialMethodCombo.addActionListener(new ActionListener() { @Override @@ -206,6 +217,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { JComboBox sectionCombo = new JComboBox( new EnumModel(component, "CrossSection")); panel.add(sectionCombo, "span, growx, wrap"); + order.add(sectionCombo); //// Thickness: @@ -216,6 +228,7 @@ public class TrapezoidFinSetConfig extends FinSetConfig { final JSpinner thicknessSpinner = new JSpinner(thicknessModel.getSpinnerModel()); thicknessSpinner.setEditor(new SpinnerEditor(thicknessSpinner)); panel.add(thicknessSpinner, "growx"); + order.add(((SpinnerEditor) thicknessSpinner.getEditor()).getTextField()); panel.add(new UnitSelector(thicknessModel), "growx"); panel.add(new BasicSlider(thicknessModel.getSliderModel(0, 0.01)), "w 100lp, wrap para"); @@ -223,7 +236,8 @@ public class TrapezoidFinSetConfig extends FinSetConfig { //// Material - panel.add(materialPanel(Material.Type.BULK), "span, wrap"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel.add(materialPanel, "span, wrap"); @@ -234,8 +248,12 @@ public class TrapezoidFinSetConfig extends FinSetConfig { tabbedPane.insertTab(trans.get("TrapezoidFinSetCfg.tab.General"), null, mainPanel, trans.get("TrapezoidFinSetCfg.tab.Generalproperties"), 0); tabbedPane.setSelectedIndex(0); - + addFinSetButtons(); - + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/TubeFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/TubeFinSetConfig.java index e9de11352..9ce17a3a9 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/TubeFinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/TubeFinSetConfig.java @@ -14,6 +14,7 @@ import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.CustomFocusTraversalPolicy; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.IntegerModel; @@ -46,6 +47,7 @@ public class TubeFinSetConfig extends RocketComponentConfig { JSpinner spin = new JSpinner(im.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx, wrap"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); //// Length: panel.add(new JLabel(trans.get("TubeFinSetCfg.lbl.Length"))); @@ -56,6 +58,7 @@ public class TubeFinSetConfig extends RocketComponentConfig { spin.setEditor(new SpinnerEditor(spin)); focusElement = spin; panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.02, 0.1)), "w 100lp, wrap para"); @@ -70,6 +73,7 @@ public class TubeFinSetConfig extends RocketComponentConfig { spin = new JSpinner(od.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(od), "growx"); panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap rel"); @@ -78,6 +82,7 @@ public class TubeFinSetConfig extends RocketComponentConfig { //// Automatic check.setText(trans.get("TubeFinSetCfg.checkbox.Automatic")); panel.add(check, "skip, span 2, wrap"); + order.add(check); //// Inner diameter: panel.add(new JLabel(trans.get("TubeFinSetCfg.lbl.Innerdiam"))); @@ -89,6 +94,7 @@ public class TubeFinSetConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "w 100lp, wrap rel"); @@ -103,6 +109,7 @@ public class TubeFinSetConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 20lp"); @@ -120,6 +127,7 @@ public class TubeFinSetConfig extends RocketComponentConfig { spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); panel.add(new UnitSelector(m), "growx"); panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap"); @@ -133,6 +141,7 @@ public class TubeFinSetConfig extends RocketComponentConfig { final EnumModel axialMethodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); final JComboBox axialMethodCombo = new JComboBox( axialMethodModel ); panel.add(axialMethodCombo, "spanx, growx, wrap"); + order.add(axialMethodCombo); //// plus panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.plus")), "right"); @@ -141,6 +150,7 @@ public class TubeFinSetConfig extends RocketComponentConfig { spin = new JSpinner(axialOffsetModel.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); panel.add(spin, "growx"); + order.add(((SpinnerEditor) spin.getEditor()).getTextField()); axialMethodCombo.addActionListener(new ActionListener() { @Override @@ -158,7 +168,8 @@ public class TubeFinSetConfig extends RocketComponentConfig { //// Material - panel.add(materialPanel(Material.Type.BULK), "span, wrap"); + MaterialPanel materialPanel = new MaterialPanel(component, document, Material.Type.BULK, order); + panel.add(materialPanel, "span, wrap"); primary.add(panel, "grow"); @@ -166,6 +177,11 @@ public class TubeFinSetConfig extends RocketComponentConfig { tabbedPane.insertTab(trans.get("LaunchLugCfg.tab.General"), null, primary, trans.get("LaunchLugCfg.tab.Generalprop"), 0); tabbedPane.setSelectedIndex(0); + + // Apply the custom focus travel policy to this config dialog + order.add(closeButton); // Make sure the close button is the last component + CustomFocusTraversalPolicy policy = new CustomFocusTraversalPolicy(order); + parent.setFocusTraversalPolicy(policy); } @Override diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java index 36b42640b..a71535a32 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java @@ -40,6 +40,7 @@ import net.sf.openrocket.rocketcomponent.SymmetricComponent; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.Chars; import net.sf.openrocket.gui.widgets.SelectColorButton; +import net.sf.openrocket.utils.TableRowTraversalPolicy; /** * Dialog shown for selecting a preset component. @@ -157,6 +158,9 @@ public class ComponentPresetChooserDialog extends JDialog { tc.setMaxWidth(w); tc.setMinWidth(w); + // The normal left/right and tab/shift-tab key action traverses each cell/column of the table instead of going to the next row. + TableRowTraversalPolicy.setTableRowTraversalPolicy(componentSelectionTable); + panel.add(getFilterCheckboxes(tm, legacyColumnIndex), "wrap para"); JScrollPane scrollpane = new JScrollPane(); diff --git a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java index bd6ad592e..5d8cd2e53 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.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -19,8 +18,6 @@ import java.util.Arrays; import java.util.Comparator; import javax.swing.AbstractAction; -import javax.swing.ActionMap; -import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; @@ -38,6 +35,7 @@ import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableCellRenderer; import net.sf.openrocket.gui.widgets.IconButton; +import net.sf.openrocket.utils.TableRowTraversalPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -178,16 +176,7 @@ public class SimulationPanel extends JPanel { pm.add(plotSimulationAction); // The normal left/right and tab/shift-tab key action traverses each cell/column of the table instead of going to the next row. - InputMap im = simulationTable.getInputMap(); - im.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "Action.NextRowCycle"); - im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "Action.NextRow"); - im.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK), "Action.PreviousRowCycle"); - im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Action.PreviousRow"); - ActionMap am = simulationTable.getActionMap(); - am.put("Action.NextRow", new NextRowAction(simulationTable, false)); - am.put("Action.NextRowCycle", new NextRowAction(simulationTable, true)); - am.put("Action.PreviousRow", new PreviousRowAction(simulationTable, false)); - am.put("Action.PreviousRowCycle", new PreviousRowAction(simulationTable, true)); + TableRowTraversalPolicy.setTableRowTraversalPolicy(simulationTable); // Mouse listener to act on double-clicks simulationTable.addMouseListener(new MouseAdapter() { @@ -1029,67 +1018,4 @@ public class SimulationPanel extends JPanel { } } } - - private static class NextRowAction extends AbstractAction { - private final JTable table; - private final boolean cycle; - - /** - * Action for cycling through the next row of the table. - * @param table table for which the action is intended - * @param cycle whether to go back to the first row if the end is reached. - */ - public NextRowAction(JTable table, boolean cycle) { - this.table = table; - this.cycle = cycle; - } - - @Override - public void actionPerformed(ActionEvent e) { - int nextRow = table.getSelectedRow() + 1; - - if (nextRow >= table.getRowCount()) { - if (cycle) { - nextRow = 0; - } else { - return; - } - } - - table.getSelectionModel().setSelectionInterval(nextRow, nextRow); - table.getColumnModel().getSelectionModel().setSelectionInterval(0, 0); - } - - } - - private static class PreviousRowAction extends AbstractAction { - private final JTable table; - private final boolean cycle; - - /** - * Action for cycling through the previous row of the table. - * @param table table for which the action is intended - * @param cycle whether to go back to the last row if the current row is the first one of the table. - */ - public PreviousRowAction(JTable table, boolean cycle) { - this.table = table; - this.cycle = cycle; - } - - @Override - public void actionPerformed(ActionEvent e) { - int nextRow = table.getSelectedRow() - 1; - - if (nextRow < 0) { - if (cycle) { - nextRow = table.getRowCount() - 1; - } else { - return; - } - } - - table.getSelectionModel().setSelectionInterval(nextRow, nextRow); - table.getColumnModel().getSelectionModel().setSelectionInterval(0, 0); - } - } } diff --git a/swing/src/net/sf/openrocket/utils/TableRowTraversalPolicy.java b/swing/src/net/sf/openrocket/utils/TableRowTraversalPolicy.java new file mode 100644 index 000000000..77623f881 --- /dev/null +++ b/swing/src/net/sf/openrocket/utils/TableRowTraversalPolicy.java @@ -0,0 +1,100 @@ +package net.sf.openrocket.utils; + +import net.sf.openrocket.gui.main.SimulationPanel; + +import javax.swing.AbstractAction; +import javax.swing.ActionMap; +import javax.swing.InputMap; +import javax.swing.JTable; +import javax.swing.KeyStroke; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +/** + * Helper class for setting a JTable to traverse rows rather than columns, when the tab/shift-tab, or right-arrow/left-arrow + * key is pressed. + * + * @author Sibo Van Gool + */ +public abstract class TableRowTraversalPolicy { + /** + * Applies the row traversal policy to the given table. + * @param table table to apply the row traversal policy to + */ + public static void setTableRowTraversalPolicy(final JTable table) { + InputMap im = table.getInputMap(); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "Action.NextRowCycle"); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "Action.NextRow"); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK), "Action.PreviousRowCycle"); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Action.PreviousRow"); + ActionMap am = table.getActionMap(); + am.put("Action.NextRow", new NextRowAction(table, false)); + am.put("Action.NextRowCycle", new NextRowAction(table, true)); + am.put("Action.PreviousRow", new PreviousRowAction(table, false)); + am.put("Action.PreviousRowCycle", new PreviousRowAction(table, true)); + } + + private static class NextRowAction extends AbstractAction { + private final JTable table; + private final boolean cycle; + + /** + * Action for cycling through the next row of the table. + * @param table table for which the action is intended + * @param cycle whether to go back to the first row if the end is reached. + */ + public NextRowAction(JTable table, boolean cycle) { + this.table = table; + this.cycle = cycle; + } + + @Override + public void actionPerformed(ActionEvent e) { + int nextRow = table.getSelectedRow() + 1; + + if (nextRow >= table.getRowCount()) { + if (cycle) { + nextRow = 0; + } else { + return; + } + } + + table.getSelectionModel().setSelectionInterval(nextRow, nextRow); + table.getColumnModel().getSelectionModel().setSelectionInterval(0, 0); + } + + } + + private static class PreviousRowAction extends AbstractAction { + private final JTable table; + private final boolean cycle; + + /** + * Action for cycling through the previous row of the table. + * @param table table for which the action is intended + * @param cycle whether to go back to the last row if the current row is the first one of the table. + */ + public PreviousRowAction(JTable table, boolean cycle) { + this.table = table; + this.cycle = cycle; + } + + @Override + public void actionPerformed(ActionEvent e) { + int nextRow = table.getSelectedRow() - 1; + + if (nextRow < 0) { + if (cycle) { + nextRow = table.getRowCount() - 1; + } else { + return; + } + } + + table.getSelectionModel().setSelectionInterval(nextRow, nextRow); + table.getColumnModel().getSelectionModel().setSelectionInterval(0, 0); + } + } +}