1 package net.sf.openrocket.gui.configdialog;
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
6 import javax.swing.JButton;
7 import javax.swing.JComboBox;
8 import javax.swing.JLabel;
9 import javax.swing.JPanel;
10 import javax.swing.JSpinner;
11 import javax.swing.SwingUtilities;
13 import net.miginfocom.swing.MigLayout;
14 import net.sf.openrocket.gui.SpinnerEditor;
15 import net.sf.openrocket.gui.adaptors.DoubleModel;
16 import net.sf.openrocket.gui.adaptors.EnumModel;
17 import net.sf.openrocket.gui.components.BasicSlider;
18 import net.sf.openrocket.gui.components.StyledLabel;
19 import net.sf.openrocket.gui.components.UnitSelector;
20 import net.sf.openrocket.gui.components.StyledLabel.Style;
21 import net.sf.openrocket.logging.LogHelper;
22 import net.sf.openrocket.rocketcomponent.FinSet;
23 import net.sf.openrocket.rocketcomponent.FreeformFinSet;
24 import net.sf.openrocket.rocketcomponent.RocketComponent;
25 import net.sf.openrocket.startup.Application;
26 import net.sf.openrocket.unit.UnitGroup;
29 public abstract class FinSetConfig extends RocketComponentConfig {
30 private static final LogHelper log = Application.getLogger();
32 private JButton split = null;
34 public FinSetConfig(RocketComponent component) {
37 tabbedPane.insertTab("Fin tabs", null, finTabPanel(), "Through-the-wall fin tabs", 0);
42 protected void addFinSetButtons() {
43 JButton convert = null;
46 if (!(component instanceof FreeformFinSet)) {
47 convert = new JButton("Convert to freeform");
48 convert.setToolTipText("Convert this fin set into a freeform fin set");
49 convert.addActionListener(new ActionListener() {
51 public void actionPerformed(ActionEvent e) {
52 log.user("Converting " + component.getComponentName() + " into freeform fin set");
54 // Do change in future for overall safety
55 SwingUtilities.invokeLater(new Runnable() {
58 ComponentConfigDialog.addUndoPosition("Convert fin set");
59 RocketComponent freeform =
60 FreeformFinSet.convertFinSet((FinSet) component);
61 ComponentConfigDialog.showDialog(freeform);
65 ComponentConfigDialog.hideDialog();
70 split = new JButton("Split fins");
71 split.setToolTipText("Split the fin set into separate fins");
72 split.addActionListener(new ActionListener() {
74 public void actionPerformed(ActionEvent e) {
75 log.user("Splitting " + component.getComponentName() + " into separate fins, fin count=" +
76 ((FinSet) component).getFinCount());
78 // Do change in future for overall safety
79 SwingUtilities.invokeLater(new Runnable() {
82 RocketComponent parent = component.getParent();
83 int index = parent.getChildPosition(component);
84 int count = ((FinSet) component).getFinCount();
85 double base = ((FinSet) component).getBaseRotation();
89 ComponentConfigDialog.addUndoPosition("Split fin set");
90 parent.removeChild(index);
91 for (int i = 0; i < count; i++) {
92 FinSet copy = (FinSet) component.copy();
94 copy.setBaseRotation(base + i * 2 * Math.PI / count);
95 copy.setName(copy.getName() + " #" + (i + 1));
96 parent.addChild(copy, index + i);
101 ComponentConfigDialog.hideDialog();
104 split.setEnabled(((FinSet) component).getFinCount() > 1);
109 addButtons(split, convert);
113 public JPanel finTabPanel() {
114 JPanel panel = new JPanel(
115 new MigLayout("align 50% 20%, fillx, gap rel unrel, ins 20lp 10% 20lp 10%",
116 "[150lp::][65lp::][30lp::][200lp::]", ""));
117 // JPanel panel = new JPanel(new MigLayout("fillx, align 20% 20%, gap rel unrel",
118 // "[40lp][80lp::][30lp::][100lp::]",""));
120 panel.add(new StyledLabel("Through-the-wall fin tabs:", Style.BOLD),
127 DoubleModel length_2;
130 length = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
131 length2 = new DoubleModel(component, "Length", 0.5, UnitGroup.UNITS_LENGTH, 0);
132 length_2 = new DoubleModel(component, "Length", -0.5, UnitGroup.UNITS_LENGTH, 0);
135 label = new JLabel("Tab length:");
136 label.setToolTipText("The length of the fin tab.");
137 panel.add(label, "gapleft para, gapright 40lp, growx 1");
139 m = new DoubleModel(component, "TabLength", UnitGroup.UNITS_LENGTH, 0);
141 spin = new JSpinner(m.getSpinnerModel());
142 spin.setEditor(new SpinnerEditor(spin));
143 panel.add(spin, "growx 1");
145 panel.add(new UnitSelector(m), "growx 1");
146 panel.add(new BasicSlider(m.getSliderModel(DoubleModel.ZERO, length)),
147 "w 100lp, growx 5, wrap");
151 label = new JLabel("Tab height:");
152 label.setToolTipText("The spanwise height of the fin tab.");
153 panel.add(label, "gapleft para");
155 m = new DoubleModel(component, "TabHeight", UnitGroup.UNITS_LENGTH, 0);
157 spin = new JSpinner(m.getSpinnerModel());
158 spin.setEditor(new SpinnerEditor(spin));
159 panel.add(spin, "growx");
161 panel.add(new UnitSelector(m), "growx");
162 panel.add(new BasicSlider(m.getSliderModel(DoubleModel.ZERO, length2)),
163 "w 100lp, growx 5, wrap para");
167 label = new JLabel("Tab position:");
168 label.setToolTipText("The position of the fin tab.");
169 panel.add(label, "gapleft para");
171 m = new DoubleModel(component, "TabShift", UnitGroup.UNITS_LENGTH);
173 spin = new JSpinner(m.getSpinnerModel());
174 spin.setEditor(new SpinnerEditor(spin));
175 panel.add(spin, "growx");
177 panel.add(new UnitSelector(m), "growx");
178 panel.add(new BasicSlider(m.getSliderModel(length_2, length2)), "w 100lp, growx 5, wrap");
182 label = new JLabel("relative to");
183 panel.add(label, "right, gapright unrel");
185 EnumModel<FinSet.TabRelativePosition> em =
186 new EnumModel<FinSet.TabRelativePosition>(component, "TabRelativePosition");
188 panel.add(new JComboBox(em), "spanx 3, growx");
194 public void updateFields() {
195 super.updateFields();
197 split.setEnabled(((FinSet) component).getFinCount() > 1);