import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
import java.util.prefs.Preferences;
import javax.swing.BorderFactory;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.motor.Motor;
-import net.sf.openrocket.motor.MotorDigest;
import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelector {
private static final LogHelper log = Application.getLogger();
private static final Translator trans = Application.getTranslator();
-
+
private static final double MOTOR_SIMILARITY_THRESHOLD = 0.95;
private static final int SHOW_ALL = 0;
private static final int SHOW_SMALLER = 1;
private static final int SHOW_EXACT = 2;
private static final String[] SHOW_DESCRIPTIONS = {
- //// Show all motors
- trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc1"),
+ //// Show all motors
+ trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc1"),
//// Show motors with diameter less than that of the motor mount
- trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc2"),
+ trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc2"),
//// Show motors with diameter equal to that of the motor mount
- trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc3")
+ trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc3")
};
private static final int SHOW_MAX = 2;
private static final ThrustCurveMotorComparator MOTOR_COMPARATOR = new ThrustCurveMotorComparator();
-
-
+
+
private final List<ThrustCurveMotorSet> database;
private final double diameter;
private CloseableDialog dialog = null;
-
+
private final ThrustCurveMotorDatabaseModel model;
private final JTable table;
private final TableRowSorter<TableModel> sorter;
private final JTextField searchField;
private String[] searchTerms = new String[0];
-
+
private final JLabel curveSelectionLabel;
private final JComboBox curveSelectionBox;
private final DefaultComboBoxModel curveSelectionModel;
private final JLabel totalImpulseLabel;
+ private final JLabel classificationLabel;
private final JLabel avgThrustLabel;
private final JLabel maxThrustLabel;
private final JLabel burnTimeLabel;
this.diameter = diameter;
-
+
// Construct the database (adding the current motor if not in the db already)
List<ThrustCurveMotorSet> db;
// TODO - ugly blind cast.
}
database = db;
-
-
+
+
//// GUI
JPanel panel;
panel = new JPanel(new MigLayout("fill"));
this.add(panel, "grow");
-
-
+
+
// Selection label
//// Select rocket motor:
label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Selrocketmotor"), Style.BOLD);
});
panel.add(hideSimilarBox, "gapleft para, spanx, growx, wrap para");
-
+
// Motor selection table
model = new ThrustCurveMotorDatabaseModel(database);
table = new JTable(model);
-
+
// Set comparators and widths
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
sorter = new TableRowSorter<TableModel>(model);
}
});
-
+
JScrollPane scrollpane = new JScrollPane();
scrollpane.setViewportView(table);
panel.add(scrollpane, "grow, width :500:, height :300:, spanx, wrap para");
-
-
-
+
+
+
// Motor mount diameter label
//// Motor mount diameter:
- label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Motormountdia")+ " " +
+ label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Motormountdia") + " " +
UnitGroup.UNITS_MOTOR_DIMENSIONS.getDefaultUnit().toStringUnit(diameter));
panel.add(label, "gapright 30lp, spanx, split");
-
-
+
+
// Search field
//// Search:
label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Search"));
String[] split = text.split("\\s+");
ArrayList<String> list = new ArrayList<String>();
for (String s : split) {
- s = s.trim().toLowerCase();
+ s = s.trim().toLowerCase(Locale.getDefault());
if (s.length() > 0) {
list.add(s);
}
});
panel.add(searchField, "growx, wrap");
-
-
+
+
// Vertical split
this.add(panel, "grow");
this.add(new JSeparator(JSeparator.VERTICAL), "growy, gap para para");
panel = new JPanel(new MigLayout("fill"));
-
-
+
+
// Thrust curve selection
//// Select thrust curve:
curveSelectionLabel = new JLabel(trans.get("TCMotorSelPan.lbl.Selectthrustcurve"));
});
panel.add(curveSelectionBox, "growx, wrap para");
-
-
-
-
+
+
+
+
// Ejection charge delay:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Ejectionchargedelay")));
panel.add(new StyledLabel(trans.get("TCMotorSelPan.lbl.NumberofsecondsorNone"), -3), "skip, wrap para");
setDelays(false);
-
+
panel.add(new JSeparator(), "spanx, growx, wrap para");
-
-
+
+
// Thrust curve info
//// Total impulse:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Totalimpulse")));
totalImpulseLabel = new JLabel();
- panel.add(totalImpulseLabel, "wrap");
+ panel.add(totalImpulseLabel, "split");
+ classificationLabel = new JLabel();
+ classificationLabel.setEnabled(false); // Gray out
+ panel.add(classificationLabel, "gapleft unrel, wrap");
//// Avg. thrust:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Avgthrust")));
digestLabel = null;
}
-
+
comment = new JTextArea(5, 5);
GUIUtil.changeFontSize(comment, -2);
withCommentFont = comment.getFont();
scrollpane = new JScrollPane(comment);
panel.add(scrollpane, "spanx, growx, wrap para");
-
-
-
+
+
+
// Thrust curve plot
chart = ChartFactory.createXYLineChart(
null, // title
false // urls
);
-
+
// Add the data and formatting to the plot
XYPlot plot = chart.getXYPlot();
zoomIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
layer.add(zoomIcon, (Integer) 1);
-
+
panel.add(layer, "width 300:300:, height 180:180:, grow, spanx");
-
-
+
+
this.add(panel, "grow");
-
-
+
+
// Sets the filter:
int showMode = Application.getPreferences().getChoice(net.sf.openrocket.startup.Preferences.MOTOR_DIAMETER_FILTER, SHOW_MAX, SHOW_EXACT);
filterComboBox.setSelectedIndex(showMode);
-
+
// Update the panel data
updateData();
selectedDelay = delay;
// Store selected motor in preferences node, set all others to false
Preferences prefs = ((SwingPreferences) Application.getPreferences()).getNode(net.sf.openrocket.startup.Preferences.PREFERRED_THRUST_CURVE_MOTOR_NODE);
for (ThrustCurveMotor m : set.getMotors()) {
- String digest = MotorDigest.digestMotor(m);
+ String digest = m.getDigest();
prefs.putBoolean(digest, m == motor);
}
}
}
-
+
private void changeLabelFont(ValueAxis axis, float size) {
Font font = axis.getTickLabelFont();
font = font.deriveFont(font.getSize2D() + size);
curveSelectionBox.setEnabled(false);
curveSelectionLabel.setEnabled(false);
totalImpulseLabel.setText("");
+ totalImpulseLabel.setToolTipText(null);
+ classificationLabel.setText("");
+ classificationLabel.setToolTipText(null);
avgThrustLabel.setText("");
maxThrustLabel.setText("");
burnTimeLabel.setText("");
return;
}
-
+
// Check which thrust curves to display
List<ThrustCurveMotor> motors = getFilteredCurves();
final int index = motors.indexOf(selectedMotor);
-
+
// Update the thrust curve selection box
curveSelectionModel.removeAllElements();
for (int i = 0; i < motors.size(); i++) {
curveSelectionLabel.setEnabled(false);
}
-
+
// Update thrust curve data
- totalImpulseLabel.setText(UnitGroup.UNITS_IMPULSE.getDefaultUnit().toStringUnit(
- selectedMotor.getTotalImpulseEstimate()));
+ double impulse = selectedMotor.getTotalImpulseEstimate();
+ MotorClass mc = MotorClass.getMotorClass(impulse);
+ totalImpulseLabel.setText(UnitGroup.UNITS_IMPULSE.getDefaultUnit().toStringUnit(impulse));
+ classificationLabel.setText("(" + mc.getDescription(impulse) + ")");
+ totalImpulseLabel.setToolTipText(mc.getClassDescription());
+ classificationLabel.setToolTipText(mc.getClassDescription());
+
avgThrustLabel.setText(UnitGroup.UNITS_FORCE.getDefaultUnit().toStringUnit(
selectedMotor.getAverageThrustEstimate()));
maxThrustLabel.setText(UnitGroup.UNITS_FORCE.getDefaultUnit().toStringUnit(
selectedMotor.getEmptyCG().weight));
dataPointsLabel.setText("" + (selectedMotor.getTimePoints().length - 1));
if (digestLabel != null) {
- digestLabel.setText(MotorDigest.digestMotor(selectedMotor));
+ digestLabel.setText(selectedMotor.getDigest());
}
setComment(selectedMotor.getDescription());
-
+
// Update the plot
XYPlot plot = chart.getXYPlot();
plot.setDataset(dataset);
}
-
private List<ThrustCurveMotor> getFilteredCurves() {
List<ThrustCurveMotor> motors = selectedMotorSet.getMotors();
if (hideSimilarBox.isSelected()) {
}
-
+
/**
* Select the default motor from this ThrustCurveMotorSet. This uses primarily motors
* that the user has previously used, and secondarily a heuristic method of selecting which
return set.getMotors().get(0);
}
-
+
// Find which motor has been used the most recently
List<ThrustCurveMotor> list = set.getMotors();
Preferences prefs = ((SwingPreferences) Application.getPreferences()).getNode(net.sf.openrocket.startup.Preferences.PREFERRED_THRUST_CURVE_MOTOR_NODE);
for (ThrustCurveMotor m : list) {
- String digest = MotorDigest.digestMotor(m);
+ String digest = m.getDigest();
if (prefs.getBoolean(digest, false)) {
return m;
}
}
if (!Double.isNaN(closest)) {
selectedDelay = closest;
- //// None
+ //// None
delayBox.setSelectedItem(ThrustCurveMotor.getDelayString(closest, trans.get("TCMotorSelPan.delayBox.None")));
} else {
delayBox.setSelectedItem("None");
} else {
selectedDelay = currentDelay;
- //// None
+ //// None
delayBox.setSelectedItem(ThrustCurveMotor.getDelayString(currentDelay, trans.get("TCMotorSelPan.delayBox.None")));
}
}
-
-
+
+
//////////////////////
-
+
private class CurveSelectionRenderer implements ListCellRenderer {
private final ListCellRenderer renderer;
public boolean filterByString(ThrustCurveMotorSet m) {
main: for (String s : searchTerms) {
for (ThrustCurveMotorColumns col : ThrustCurveMotorColumns.values()) {
- String str = col.getValue(m).toString().toLowerCase();
+ String str = col.getValue(m).toString().toLowerCase(Locale.getDefault());
if (str.indexOf(s) >= 0)
continue main;
}