diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties
index 761eab5e5..85aef3d1d 100644
--- a/core/resources/l10n/messages.properties
+++ b/core/resources/l10n/messages.properties
@@ -972,8 +972,6 @@ RocketCompCfg.checkbox.Endcapped = End capped
RocketCompCfg.checkbox.Endcapped.ttip = Caps (closes) the end of the shoulder.
RocketCompCfg.title.Aftshoulder = Aft shoulder
RocketCompCfg.border.Foreshoulder = Fore shoulder
-RocketCompCfg.lbl.InstanceCount = Instance Count:
-RocketCompCfg.lbl.InstanceSeparation = Instance Separation:
RocketCompCfg.tab.Outside = Outside
RocketCompCfg.tab.Inside = Inside
RocketCompCfg.tab.RightSide = Right Side
@@ -986,6 +984,11 @@ RocketCompCfg.CancelOperation.title = Cancel operation
RocketCompCfg.CancelOperation.checkbox.dontAskAgain = Don't ask me again
RocketCompCfg.btn.ComponentInfo.ttip = Show/hide informative text about this component.
+! InstancesPanel
+InstancesPanel.title.Instances = Instances
+InstancesPanel.lbl.InstanceCount = Instance Count:
+InstancesPanel.lbl.InstanceSeparation = Instance Separation:
+
! MaterialPanel
MaterialPanel.lbl.ComponentMaterial = Component material:
MaterialPanel.lbl.ComponentFinish = Component finish:
diff --git a/core/resources/l10n/messages_ar.properties b/core/resources/l10n/messages_ar.properties
index 091cc2a57..83e5d0b1d 100644
--- a/core/resources/l10n/messages_ar.properties
+++ b/core/resources/l10n/messages_ar.properties
@@ -962,13 +962,15 @@ RocketCompCfg.checkbox.Endcapped.ttip = .يغلق نهاية الكتف
RocketCompCfg.title.Aftshoulder = مؤخرة الكتف
RocketCompCfg.border.Foreshoulder = مقدمة الكتف
!RocketCompCfg.lbl.Length = :الطول
-RocketCompCfg.lbl.InstanceCount = عدد المثيل
-RocketCompCfg.lbl.InstanceSeparation = فصل المثيل
RocketCompCfg.tab.Outside = من الخارج
RocketCompCfg.tab.Inside = من الداخل
RocketCompCfg.tab.RightSide = الجانب اليميني
RocketCompCfg.tab.LeftSide = الجانب اليساري
+! InstancesPanel
+InstancesPanel.lbl.InstanceCount = عدد المثيل
+InstancesPanel.lbl.InstanceSeparation = فصل المثيل
+
! ComponentInfo
ComponentInfo.EngineBlock = .كتلة المحرك تمنعه من التحرك للأمام في أنبوب الحامل للمحرك
.من أجل إضافة محرك ، قم بإنشاء أنبوب جسم أو أنبوب داخلي وقم بتمييزه على أنه حامل محرك في علامة تبويب المحرك
diff --git a/core/resources/l10n/messages_nl.properties b/core/resources/l10n/messages_nl.properties
index cae1b039c..b88be2277 100644
--- a/core/resources/l10n/messages_nl.properties
+++ b/core/resources/l10n/messages_nl.properties
@@ -909,8 +909,6 @@ RocketCompCfg.ttip.Endcapped = Of het einde van de schouder is afgedekt.
RocketCompCfg.title.Aftshoulder = Achterschouder
RocketCompCfg.border.Foreshoulder = Voorschouder
!RocketCompCfg.lbl.Length = Lengte:
-RocketCompCfg.lbl.InstanceCount = Aantal instanties
-RocketCompCfg.lbl.InstanceSeparation = Instantie afstand
RocketCompCfg.tab.Outside = Buitenkant
RocketCompCfg.tab.Inside = Binnenkant
RocketCompCfg.tab.RightSide = Rechterkant
@@ -923,6 +921,10 @@ RocketCompCfg.CancelOperation.title = Annuleren
RocketCompCfg.CancelOperation.checkbox.dontAskAgain = Vraag me niet opnieuw
RocketCompCfg.btn.ComponentInfo.ttip = Toon/verberg informatieve text over deze component.
+! InstancesPanel
+InstancesPanel.lbl.InstanceCount = Aantal instanties
+InstancesPanel.lbl.InstanceSeparation = Instantie afstand
+
! ComponentInfo
ComponentInfo.EngineBlock = Een motorblok voorkomt dat de motor voorwaarts beweegt in de buis van de motorsteun.
Om een motor toe te voegen, maak een rompbuis of binnenbuis en markeer het als een motorbevestiging in het Motortabblad.
diff --git a/core/resources/l10n/messages_ru.properties b/core/resources/l10n/messages_ru.properties
index 897236d24..f2e16837a 100644
--- a/core/resources/l10n/messages_ru.properties
+++ b/core/resources/l10n/messages_ru.properties
@@ -940,13 +940,15 @@ RocketCompCfg.checkbox.Endcapped.ttip = \u0417\u0430\u0433\u043B\u0443\u0448\u04
RocketCompCfg.title.Aftshoulder = \u0417\u0430\u0434\u043D\u0438\u0439 \u0432\u044B\u0441\u0442\u0443\u043F
RocketCompCfg.border.Foreshoulder = \u041F\u0435\u0440\u0435\u0434\u043D\u0438\u0439 \u0432\u044B\u0441\u0442\u0443\u043F
!RocketCompCfg.lbl.Length = \u0414\u043B\u0438\u043D\u0430:
-RocketCompCfg.lbl.InstanceCount = \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440\u043E\u0432
-RocketCompCfg.lbl.InstanceSeparation = \u0420\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440\u043E\u0432
RocketCompCfg.tab.Outside = \u0421\u043D\u0430\u0440\u0443\u0436\u0438
RocketCompCfg.tab.Inside = \u0412\u043D\u0443\u0442\u0440\u0438
RocketCompCfg.tab.RightSide = \u0421\u043F\u0440\u0430\u0432\u0430
RocketCompCfg.tab.LeftSide = \u0421\u043B\u0435\u0432\u0430
+! InstancesPanel
+InstancesPanel.lbl.InstanceCount = \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440\u043E\u0432
+InstancesPanel.lbl.InstanceSeparation = \u0420\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440\u043E\u0432
+
! ComponentInfo
ComponentInfo.EngineBlock = \u0423\u043F\u043E\u0440 \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u044F \u043F\u0440\u0435\u043F\u044F\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0432\u0438\u0436\u0435\u043D\u0438\u044E \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u044F \u0432\u043F\u0435\u0440\u0435\u0434 \u0432 \u0442\u0440\u0443\u0431\u0435.
\u0414\u043B\u044F \u0442\u043E\u0433\u043E \u0447\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u044C, \u0441\u043E\u0437\u0434\u0430\u0439\u0442\u0435 \u041A\u043E\u0440\u043F\u0443\u0441\u043D\u0443\u044E \u0442\u0440\u0443\u0431\u0443 \u0438\u043B\u0438 \u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044E\u044E \u0442\u0440\u0443\u0431\u0443 \u0438 \u043E\u0442\u043C\u0435\u0442\u044C\u0442\u0435 \u044D\u0442\u043E\u0442 \u044D\u043B\u0435\u043C\u0435\u043D\u0442 \u043A\u0430\u043A \u043A\u0440\u0435\u043F\u0435\u0436 \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u044F \u043D\u0430 \u0432\u043A\u043B\u0430\u0434\u043A\u0435 \u0414\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u044C .
diff --git a/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java b/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java
index 48804f2b8..aeda57cb3 100644
--- a/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java
+++ b/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java
@@ -274,7 +274,11 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
}
}
+ if (MathUtil.equals(this.instanceSeparation, _separation)) {
+ return;
+ }
this.instanceSeparation = _separation;
+ fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
}
@Override
@@ -285,9 +289,11 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
}
}
- if( 0 < newCount ){
- this.instanceCount = newCount;
+ if (newCount == this.instanceCount || newCount <= 0) {
+ return;
}
+ this.instanceCount = newCount;
+ fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
diff --git a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java
index a25e616a0..499795fc0 100644
--- a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java
+++ b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java
@@ -320,6 +320,9 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
}
+ if (MathUtil.equals(this.instanceSeparation, _separation)) {
+ return;
+ }
this.instanceSeparation = _separation;
fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
}
@@ -332,9 +335,10 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
}
- if( 0 < newCount ){
- this.instanceCount = newCount;
+ if (newCount == this.instanceCount || newCount <= 0) {
+ return;
}
+ this.instanceCount = newCount;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
diff --git a/swing/src/net/sf/openrocket/gui/configdialog/InstancesPanel.java b/swing/src/net/sf/openrocket/gui/configdialog/InstancesPanel.java
new file mode 100644
index 000000000..3a10c7db0
--- /dev/null
+++ b/swing/src/net/sf/openrocket/gui/configdialog/InstancesPanel.java
@@ -0,0 +1,61 @@
+package net.sf.openrocket.gui.configdialog;
+
+import net.miginfocom.swing.MigLayout;
+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.components.BasicSlider;
+import net.sf.openrocket.gui.components.UnitSelector;
+import net.sf.openrocket.l10n.Translator;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.rocketcomponent.position.AxialMethod;
+import net.sf.openrocket.startup.Application;
+import net.sf.openrocket.unit.UnitGroup;
+
+import javax.swing.BorderFactory;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.EventObject;
+import java.util.List;
+
+/**
+ * Panel for configuring a component's duplication instances.
+ */
+public class InstancesPanel extends JPanel {
+ private static final Translator trans = Application.getTranslator();
+
+ public InstancesPanel(RocketComponent component, List order) {
+ super(new MigLayout("gap rel unrel", "[][65lp::][30lp::]"));
+ this.setBorder(BorderFactory.createTitledBorder(trans.get("InstancesPanel.title.Instances")));
+
+ {//// Instance Count
+ add(new JLabel(trans.get("InstancesPanel.lbl.InstanceCount")));
+ IntegerModel countModel = new IntegerModel(component, "InstanceCount", 1);
+ JSpinner countSpinner = new JSpinner( countModel.getSpinnerModel());
+ countSpinner.setEditor(new SpinnerEditor(countSpinner));
+ add(countSpinner, "growx, wrap rel");
+ order.add(((SpinnerEditor) countSpinner.getEditor()).getTextField());
+ }
+
+ { //// Instance separation
+ add(new JLabel(trans.get("InstancesPanel.lbl.InstanceSeparation")));
+ DoubleModel separationModel = new DoubleModel(component, "InstanceSeparation", UnitGroup.UNITS_LENGTH);
+ JSpinner separationSpinner = new JSpinner( separationModel.getSpinnerModel());
+ separationSpinner.setEditor(new SpinnerEditor(separationSpinner));
+ add(separationSpinner, "growx");
+ order.add(((SpinnerEditor) separationSpinner.getEditor()).getTextField());
+ add(new UnitSelector(separationModel), "growx");
+ double maxSeparationDistance = 0.1;
+ if (component.getParent() != null && component.getParent().getLength() > 0) {
+ maxSeparationDistance = component.getParent().getLength();
+ }
+ add(new BasicSlider(separationModel.getSliderModel(0, 0.001, maxSeparationDistance)), "w 100lp, wrap para");
+ }
+ }
+}
diff --git a/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java
index bb19fa015..423256ebe 100644
--- a/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java
+++ b/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java
@@ -92,7 +92,10 @@ public class LaunchLugConfig extends RocketComponentConfig {
order.add(((SpinnerEditor) spin.getEditor()).getTextField());
panel.add(new UnitSelector(m), "growx");
- panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap");
+ panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 30lp");
+
+ // -------- Instances ------
+ panel.add(new InstancesPanel(component, order), "span, grow, wrap para");
primary.add(panel, "grow, gapright 40lp");
diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java
index 1c6d3c53e..3ee156995 100644
--- a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java
+++ b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java
@@ -111,29 +111,8 @@ public class RailButtonConfig extends RocketComponentConfig {
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.02)), "w 100lp, wrap 30lp");
}
- { //// Instance Count
- panel.add(new JLabel(trans.get("RocketCompCfg.lbl.InstanceCount")));
- IntegerModel countModel = new IntegerModel(component, "InstanceCount", 1);
- JSpinner countSpinner = new JSpinner( countModel.getSpinnerModel());
- countSpinner.setEditor(new SpinnerEditor(countSpinner));
- panel.add(countSpinner, "growx, wrap rel");
- order.add(((SpinnerEditor) countSpinner.getEditor()).getTextField());
- }
-
- { //// Instance separation
- panel.add(new JLabel(trans.get("RocketCompCfg.lbl.InstanceSeparation")));
- DoubleModel separationModel = new DoubleModel(component, "InstanceSeparation", UnitGroup.UNITS_LENGTH);
- 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) {
- maxSeparationDistance = component.getParent().getLength();
- }
- panel.add(new BasicSlider(separationModel.getSliderModel(0, 0.001, maxSeparationDistance)), "w 100lp, wrap para");
- }
+ // -------- Instances ------
+ panel.add(new InstancesPanel(component, order), "span, grow, wrap para");
primary.add(panel, "grow, gapright 40lp");