Rework the thrustcurve motor filter and information. They now share

tabs on the MotorSelectionPanel.  Added Minimum Motor diameter to the
motor filter.
This commit is contained in:
kruland2607 2013-10-04 20:36:30 -05:00
parent 32817f2cb1
commit e6755e0e84
5 changed files with 888 additions and 810 deletions

View File

@ -1088,6 +1088,7 @@ StorageOptChooser.lbl.Saveopt = Save options
TCMotorSelPan.lbl.Selrocketmotor = Select rocket motor: TCMotorSelPan.lbl.Selrocketmotor = Select rocket motor:
TCMotorSelPan.checkbox.hideSimilar = Hide very similar thrust curves TCMotorSelPan.checkbox.hideSimilar = Hide very similar thrust curves
TCMotorSelPan.checkbox.hideUsed = Hide motors already used in the mount TCMotorSelPan.checkbox.hideUsed = Hide motors already used in the mount
TCMotorSelPan.btn.details = Show Details
TCMotorSelPan.btn.filter = Filter Motors TCMotorSelPan.btn.filter = Filter Motors
TCMotorSelPan.SHOW_DESCRIPTIONS.desc1 = Show all motors TCMotorSelPan.SHOW_DESCRIPTIONS.desc1 = Show all motors
TCMotorSelPan.SHOW_DESCRIPTIONS.desc2 = Show motors with diameter less than that of the motor mount TCMotorSelPan.SHOW_DESCRIPTIONS.desc2 = Show motors with diameter less than that of the motor mount

View File

@ -12,25 +12,34 @@ import java.util.List;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.ButtonGroup; import javax.swing.ButtonGroup;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton; import javax.swing.JRadioButton;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener; import javax.swing.event.ListDataListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.util.CheckList; import net.sf.openrocket.gui.util.CheckList;
import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.motor.Manufacturer; import net.sf.openrocket.motor.Manufacturer;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
import com.itextpdf.text.Font; import com.itextpdf.text.Font;
public abstract class MotorFilterPopupMenu extends JPopupMenu { public abstract class MotorFilterPanel extends JPanel {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
@ -39,6 +48,8 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
private final CheckList<ImpulseClass> impulseCheckList; private final CheckList<ImpulseClass> impulseCheckList;
private final MotorRowFilter filter; private final MotorRowFilter filter;
private final TitledBorder diameterTitleBorder;
private final DoubleModel mountDiameter = new DoubleModel(1);
private int showMode = SHOW_ALL; private int showMode = SHOW_ALL;
@ -47,13 +58,24 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
private static final int SHOW_EXACT = 2; private static final int SHOW_EXACT = 2;
private static final int SHOW_MAX = 2; private static final int SHOW_MAX = 2;
public MotorFilterPanel(Collection<Manufacturer> allManufacturers, MotorRowFilter filter ) {
public MotorFilterPopupMenu(Collection<Manufacturer> allManufacturers, MotorRowFilter filter ) { super(new MigLayout("fill", "[grow]"));
this.filter = filter; this.filter = filter;
showMode = Application.getPreferences().getChoice(net.sf.openrocket.startup.Preferences.MOTOR_DIAMETER_FILTER, MotorFilterPopupMenu.SHOW_MAX, MotorFilterPopupMenu.SHOW_EXACT); showMode = Application.getPreferences().getChoice(net.sf.openrocket.startup.Preferences.MOTOR_DIAMETER_FILTER, MotorFilterPanel.SHOW_MAX, MotorFilterPanel.SHOW_EXACT);
switch( showMode ) {
case SHOW_ALL:
filter.setDiameterControl(MotorRowFilter.DiameterFilterControl.ALL);
break;
case SHOW_EXACT:
filter.setDiameterControl(MotorRowFilter.DiameterFilterControl.EXACT);
break;
case SHOW_SMALLER:
filter.setDiameterControl(MotorRowFilter.DiameterFilterControl.SMALLER);
break;
}
List<Manufacturer> unselectedManusFromPreferences = ((SwingPreferences) Application.getPreferences()).getExcludedMotorManufacturers(); List<Manufacturer> unselectedManusFromPreferences = ((SwingPreferences) Application.getPreferences()).getExcludedMotorManufacturers();
filter.setExcludedManufacturers(unselectedManusFromPreferences);
// Manufacturer selection // Manufacturer selection
JPanel sub = new JPanel(new MigLayout("fill")); JPanel sub = new JPanel(new MigLayout("fill"));
@ -61,8 +83,7 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
GUIUtil.changeFontStyle(border, Font.BOLD); GUIUtil.changeFontStyle(border, Font.BOLD);
sub.setBorder(border); sub.setBorder(border);
JPanel root = new JPanel(new MigLayout("fill", "[grow]")); this.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
root.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
List<Manufacturer> manufacturers = new ArrayList<Manufacturer>(); List<Manufacturer> manufacturers = new ArrayList<Manufacturer>();
for (Manufacturer m : allManufacturers) { for (Manufacturer m : allManufacturers) {
@ -81,7 +102,6 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
manufacturerCheckList.setData(manufacturers); manufacturerCheckList.setData(manufacturers);
manufacturerCheckList.setUncheckedItems(unselectedManusFromPreferences); manufacturerCheckList.setUncheckedItems(unselectedManusFromPreferences);
filter.setExcludedManufacturers(unselectedManusFromPreferences);
manufacturerCheckList.getModel().addListDataListener( new ListDataListener() { manufacturerCheckList.getModel().addListDataListener( new ListDataListener() {
@Override @Override
public void intervalAdded(ListDataEvent e) { public void intervalAdded(ListDataEvent e) {
@ -92,7 +112,7 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
@Override @Override
public void contentsChanged(ListDataEvent e) { public void contentsChanged(ListDataEvent e) {
MotorFilterPopupMenu.this.filter.setExcludedManufacturers( manufacturerCheckList.getUncheckedItems() ); MotorFilterPanel.this.filter.setExcludedManufacturers( manufacturerCheckList.getUncheckedItems() );
onSelectionChanged(); onSelectionChanged();
} }
}); });
@ -103,7 +123,7 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
clearMotors.addActionListener( new ActionListener() { clearMotors.addActionListener( new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
MotorFilterPopupMenu.this.manufacturerCheckList.clearAll(); MotorFilterPanel.this.manufacturerCheckList.clearAll();
} }
}); });
@ -114,14 +134,14 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
selectMotors.addActionListener( new ActionListener() { selectMotors.addActionListener( new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
MotorFilterPopupMenu.this.manufacturerCheckList.checkAll(); MotorFilterPanel.this.manufacturerCheckList.checkAll();
} }
}); });
sub.add(selectMotors,"wrap"); sub.add(selectMotors,"wrap");
root.add(sub,"grow, wrap"); this.add(sub,"grow, wrap");
// Impulse selection // Impulse selection
sub = new JPanel(new MigLayout("fill")); sub = new JPanel(new MigLayout("fill"));
@ -141,7 +161,7 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
} }
@Override @Override
public void contentsChanged(ListDataEvent e) { public void contentsChanged(ListDataEvent e) {
MotorFilterPopupMenu.this.filter.setExcludedImpulseClasses( impulseCheckList.getUncheckedItems() ); MotorFilterPanel.this.filter.setExcludedImpulseClasses( impulseCheckList.getUncheckedItems() );
onSelectionChanged(); onSelectionChanged();
} }
@ -153,7 +173,7 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
clearImpulse.addActionListener( new ActionListener() { clearImpulse.addActionListener( new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
MotorFilterPopupMenu.this.impulseCheckList.clearAll(); MotorFilterPanel.this.impulseCheckList.clearAll();
} }
}); });
@ -163,27 +183,28 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
selectImpulse.addActionListener( new ActionListener() { selectImpulse.addActionListener( new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
MotorFilterPopupMenu.this.impulseCheckList.checkAll(); MotorFilterPanel.this.impulseCheckList.checkAll();
} }
}); });
sub.add(selectImpulse,"wrap"); sub.add(selectImpulse,"wrap");
root.add(sub,"grow, wrap"); this.add(sub,"grow, wrap");
// Diameter selection // Diameter selection
sub = new JPanel(new MigLayout("fill")); sub = new JPanel(new MigLayout("fill"));
border = BorderFactory.createTitledBorder(trans.get("TCurveMotorCol.DIAMETER")); diameterTitleBorder = BorderFactory.createTitledBorder(trans.get("TCurveMotorCol.DIAMETER"));
GUIUtil.changeFontStyle(border, Font.BOLD); GUIUtil.changeFontStyle(diameterTitleBorder, Font.BOLD);
sub.setBorder(border); sub.setBorder(diameterTitleBorder);
JRadioButton showAllDiametersButton = new JRadioButton( trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc1") ); JRadioButton showAllDiametersButton = new JRadioButton( trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc1") );
showAllDiametersButton.addActionListener( new ActionListener() { showAllDiametersButton.addActionListener( new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
showMode = SHOW_ALL; showMode = SHOW_ALL;
MotorFilterPopupMenu.this.filter.setDiameterControl(MotorRowFilter.DiameterFilterControl.ALL); MotorFilterPanel.this.filter.setDiameterControl(MotorRowFilter.DiameterFilterControl.ALL);
saveMotorDiameterMatchPrefence();
onSelectionChanged(); onSelectionChanged();
} }
}); });
@ -195,7 +216,8 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
showMode = SHOW_SMALLER; showMode = SHOW_SMALLER;
MotorFilterPopupMenu.this.filter.setDiameterControl(MotorRowFilter.DiameterFilterControl.SMALLER); MotorFilterPanel.this.filter.setDiameterControl(MotorRowFilter.DiameterFilterControl.SMALLER);
saveMotorDiameterMatchPrefence();
onSelectionChanged(); onSelectionChanged();
} }
}); });
@ -207,43 +229,57 @@ public abstract class MotorFilterPopupMenu extends JPopupMenu {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
showMode = SHOW_EXACT; showMode = SHOW_EXACT;
MotorFilterPopupMenu.this.filter.setDiameterControl(MotorRowFilter.DiameterFilterControl.EXACT); MotorFilterPanel.this.filter.setDiameterControl(MotorRowFilter.DiameterFilterControl.EXACT);
saveMotorDiameterMatchPrefence();
onSelectionChanged(); onSelectionChanged();
} }
}); });
showExactDiametersButton.setSelected( showMode == SHOW_EXACT ); showExactDiametersButton.setSelected( showMode == SHOW_EXACT );
sub.add(showExactDiametersButton, "growx,wrap"); sub.add(showExactDiametersButton, "growx,wrap");
root.add(sub, "grow,wrap");
ButtonGroup comboGroup = new ButtonGroup(); ButtonGroup comboGroup = new ButtonGroup();
comboGroup.add( showAllDiametersButton ); comboGroup.add( showAllDiametersButton );
comboGroup.add( showSmallerDiametersButton ); comboGroup.add( showSmallerDiametersButton );
comboGroup.add( showExactDiametersButton ); comboGroup.add( showExactDiametersButton );
{
// Close button sub.add( new JLabel("Minimum diameter"), "split 4");
JButton closeButton = new JButton(trans.get("TCMotorSelPan.btn.close")); final DoubleModel minDiameter = new DoubleModel(0, UnitGroup.UNITS_MOTOR_DIMENSIONS, 0, .2);
closeButton.addActionListener(new ActionListener() { minDiameter.addChangeListener( new ChangeListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void stateChanged(ChangeEvent e) {
MotorFilterPopupMenu.this.onClose(); MotorFilterPanel.this.filter.setMinimumDiameter(minDiameter.getValue());
onSelectionChanged();
} }
}); });
root.add(closeButton, "split 2"); JSpinner spin = new JSpinner(minDiameter.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
sub.add(spin, "growx");
this.add(root); sub.add(new UnitSelector(minDiameter));
sub.add(new BasicSlider(minDiameter.getSliderModel(0,0.5, mountDiameter)), "w 100lp, wrap");
}
this.add(sub, "grow,wrap");
} }
public void onClose() { public void setMotorMount( MotorMount mount ) {
filter.setMotorMount(mount);
onSelectionChanged();
if ( mount == null ) {
// Disable diameter controls?
diameterTitleBorder.setTitle(trans.get("TCurveMotorCol.DIAMETER"));
mountDiameter.setValue(1.0);
} else {
mountDiameter.setValue(mount.getMotorMountDiameter());
diameterTitleBorder.setTitle(trans.get("TCurveMotorCol.DIAMETER") + " "
+ trans.get("TCMotorSelPan.lbl.Motormountdia") + " " +
UnitGroup.UNITS_MOTOR_DIMENSIONS.getDefaultUnit().toStringUnit(mount.getMotorMountDiameter()));
((SwingPreferences) Application.getPreferences()).setExcludedMotorManufacturers(filter.getExcludedManufacturers()); }
}
private void saveMotorDiameterMatchPrefence() {
Application.getPreferences().putChoice("MotorDiameterMatch", showMode ); Application.getPreferences().putChoice("MotorDiameterMatch", showMode );
setVisible(false);
} }
public abstract void onSelectionChanged(); public abstract void onSelectionChanged();

View File

@ -0,0 +1,315 @@
package net.sf.openrocket.gui.dialogs.motor.thrustcurve;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.Icons;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
class MotorInformationPanel extends JPanel {
private static final int ZOOM_ICON_POSITION_NEGATIVE_X = 50;
private static final int ZOOM_ICON_POSITION_POSITIVE_Y = 12;
private static final Color NO_COMMENT_COLOR = Color.GRAY;
private static final Color WITH_COMMENT_COLOR = Color.BLACK;
private static final Translator trans = Application.getTranslator();
// Motors in set
private List<ThrustCurveMotor> selectedMotorSet;
// Selected motor
private ThrustCurveMotor selectedMotor;
private final JLabel totalImpulseLabel;
private final JLabel classificationLabel;
private final JLabel avgThrustLabel;
private final JLabel maxThrustLabel;
private final JLabel burnTimeLabel;
private final JLabel launchMassLabel;
private final JLabel emptyMassLabel;
private final JLabel dataPointsLabel;
private final JLabel digestLabel;
private final JTextArea comment;
private final Font noCommentFont;
private final Font withCommentFont;
private final JFreeChart chart;
private final ChartPanel chartPanel;
private final JLabel zoomIcon;
public MotorInformationPanel() {
super(new MigLayout("fill"));
// Thrust curve info
//// Total impulse:
{
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Totalimpulse")));
totalImpulseLabel = new JLabel();
this.add(totalImpulseLabel, "split");
classificationLabel = new JLabel();
classificationLabel.setEnabled(false); // Gray out
this.add(classificationLabel, "gapleft unrel, wrap");
//// Avg. thrust:
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Avgthrust")));
avgThrustLabel = new JLabel();
this.add(avgThrustLabel, "wrap");
//// Max. thrust:
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Maxthrust")));
maxThrustLabel = new JLabel();
this.add(maxThrustLabel, "wrap");
//// Burn time:
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Burntime")));
burnTimeLabel = new JLabel();
this.add(burnTimeLabel, "wrap");
//// Launch mass:
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Launchmass")));
launchMassLabel = new JLabel();
this.add(launchMassLabel, "wrap");
//// Empty mass:
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Emptymass")));
emptyMassLabel = new JLabel();
this.add(emptyMassLabel, "wrap");
//// Data points:
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Datapoints")));
dataPointsLabel = new JLabel();
this.add(dataPointsLabel, "wrap para");
if (System.getProperty("openrocket.debug.motordigest") != null) {
//// Digest:
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Digest")));
digestLabel = new JLabel();
this.add(digestLabel, "w :300:, wrap para");
} else {
digestLabel = null;
}
comment = new JTextArea(5, 5);
GUIUtil.changeFontSize(comment, -2);
withCommentFont = comment.getFont();
noCommentFont = withCommentFont.deriveFont(Font.ITALIC);
comment.setLineWrap(true);
comment.setWrapStyleWord(true);
comment.setEditable(false);
JScrollPane scrollpane = new JScrollPane(comment);
this.add(scrollpane, "spanx, growx, wrap para");
}
// Thrust curve plot
{
chart = ChartFactory.createXYLineChart(
null, // title
null, // xAxisLabel
null, // yAxisLabel
null, // dataset
PlotOrientation.VERTICAL,
false, // legend
false, // tooltips
false // urls
);
// Add the data and formatting to the plot
XYPlot plot = chart.getXYPlot();
changeLabelFont(plot.getRangeAxis(), -2);
changeLabelFont(plot.getDomainAxis(), -2);
//// Thrust curve:
chart.setTitle(new TextTitle(trans.get("TCMotorSelPan.title.Thrustcurve"), this.getFont()));
chart.setBackgroundPaint(this.getBackground());
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
chartPanel = new ChartPanel(chart,
false, // properties
false, // save
false, // print
false, // zoom
false); // tooltips
chartPanel.setMouseZoomable(false);
chartPanel.setPopupMenu(null);
chartPanel.setMouseWheelEnabled(false);
chartPanel.setRangeZoomable(false);
chartPanel.setDomainZoomable(false);
chartPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
chartPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (selectedMotor == null || selectedMotorSet == null)
return;
if (e.getButton() == MouseEvent.BUTTON1) {
// Open plot dialog
ThrustCurveMotorPlotDialog plotDialog = new ThrustCurveMotorPlotDialog(selectedMotorSet,
selectedMotorSet.indexOf(selectedMotor),
SwingUtilities.getWindowAncestor(MotorInformationPanel.this));
plotDialog.setVisible(true);
}
}
});
JLayeredPane layer = new CustomLayeredPane();
layer.setBorder(BorderFactory.createLineBorder(Color.BLUE));
layer.add(chartPanel, (Integer) 0);
zoomIcon = new JLabel(Icons.ZOOM_IN);
zoomIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
layer.add(zoomIcon, (Integer) 1);
this.add(layer, "width 300:300:, height 180:180:, grow, spanx");
}
}
public void clearData() {
totalImpulseLabel.setText("");
totalImpulseLabel.setToolTipText(null);
classificationLabel.setText("");
classificationLabel.setToolTipText(null);
avgThrustLabel.setText("");
maxThrustLabel.setText("");
burnTimeLabel.setText("");
launchMassLabel.setText("");
emptyMassLabel.setText("");
dataPointsLabel.setText("");
if (digestLabel != null) {
digestLabel.setText("");
}
setComment("");
chart.getXYPlot().setDataset(new XYSeriesCollection());
}
public void updateData( List<ThrustCurveMotor> motors, ThrustCurveMotor selectedMotor ) {
this.selectedMotorSet = motors;
this.selectedMotor = selectedMotor;
// Update thrust curve data
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.getMaxThrustEstimate()));
burnTimeLabel.setText(UnitGroup.UNITS_SHORT_TIME.getDefaultUnit().toStringUnit(
selectedMotor.getBurnTimeEstimate()));
launchMassLabel.setText(UnitGroup.UNITS_MASS.getDefaultUnit().toStringUnit(
selectedMotor.getLaunchCG().weight));
emptyMassLabel.setText(UnitGroup.UNITS_MASS.getDefaultUnit().toStringUnit(
selectedMotor.getEmptyCG().weight));
dataPointsLabel.setText("" + (selectedMotor.getTimePoints().length - 1));
if (digestLabel != null) {
digestLabel.setText(selectedMotor.getDigest());
}
setComment(selectedMotor.getDescription());
// Update the plot
XYPlot plot = chart.getXYPlot();
final int index = motors.indexOf(selectedMotor);
XYSeriesCollection dataset = new XYSeriesCollection();
for (int i = 0; i < motors.size(); i++) {
ThrustCurveMotor m = motors.get(i);
//// Thrust
XYSeries series = new XYSeries(trans.get("TCMotorSelPan.title.Thrust") + " (" + i + ")");
double[] time = m.getTimePoints();
double[] thrust = m.getThrustPoints();
for (int j = 0; j < time.length; j++) {
series.add(time[j], thrust[j]);
}
dataset.addSeries(series);
boolean selected = (i == index);
plot.getRenderer().setSeriesStroke(i, new BasicStroke(selected ? 3 : 1));
plot.getRenderer().setSeriesPaint(i, ThrustCurveMotorSelectionPanel.getColor(i));
}
plot.setDataset(dataset);
}
private void setComment(String s) {
s = s.trim();
if (s.length() == 0) {
//// No description available.
comment.setText(trans.get("TCMotorSelPan.noDescription"));
comment.setFont(noCommentFont);
comment.setForeground(NO_COMMENT_COLOR);
} else {
comment.setText(s);
comment.setFont(withCommentFont);
comment.setForeground(WITH_COMMENT_COLOR);
}
comment.setCaretPosition(0);
}
void changeLabelFont(ValueAxis axis, float size) {
Font font = axis.getTickLabelFont();
font = font.deriveFont(font.getSize2D() + size);
axis.setTickLabelFont(font);
}
/**
* Custom layered pane that sets the bounds of the components on every layout.
*/
public class CustomLayeredPane extends JLayeredPane {
@Override
public void doLayout() {
synchronized (getTreeLock()) {
int w = getWidth();
int h = getHeight();
chartPanel.setBounds(0, 0, w, h);
zoomIcon.setBounds(w - ZOOM_ICON_POSITION_NEGATIVE_X, ZOOM_ICON_POSITION_POSITIVE_Y, 50, 50);
}
}
}
}

View File

@ -35,7 +35,10 @@ class MotorRowFilter extends RowFilter<TableModel, Integer> {
// things which can be changed to modify filter behavior // things which can be changed to modify filter behavior
// Collection of strings which match text in the moto // Limit motors based on minimum diameter
private Double minimumDiameter;
// Collection of strings which match text in the motor
private List<String> searchTerms = Collections.<String> emptyList(); private List<String> searchTerms = Collections.<String> emptyList();
// Limit motors based on diameter of the motor mount // Limit motors based on diameter of the motor mount
@ -76,6 +79,14 @@ class MotorRowFilter extends RowFilter<TableModel, Integer> {
} }
} }
Double getMinimumDiameter() {
return minimumDiameter;
}
void setMinimumDiameter(Double minimumDiameter) {
this.minimumDiameter = minimumDiameter;
}
DiameterFilterControl getDiameterControl() { DiameterFilterControl getDiameterControl() {
return diameterControl; return diameterControl;
} }
@ -130,6 +141,13 @@ class MotorRowFilter extends RowFilter<TableModel, Integer> {
} }
private boolean filterByDiameter(ThrustCurveMotorSet m) { private boolean filterByDiameter(ThrustCurveMotorSet m) {
if ( minimumDiameter != null ) {
if ( m.getDiameter() <= minimumDiameter - 0.0015 ) {
return false;
}
}
if (diameter == null) { if (diameter == null) {
return true; return true;
} }

View File

@ -1,9 +1,7 @@
package net.sf.openrocket.gui.dialogs.motor.thrustcurve; package net.sf.openrocket.gui.dialogs.motor.thrustcurve;
import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Cursor;
import java.awt.Font; import java.awt.Font;
import java.awt.Paint; import java.awt.Paint;
import java.awt.Rectangle; import java.awt.Rectangle;
@ -20,26 +18,24 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.ListCellRenderer; import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.RowSorter; import javax.swing.RowSorter;
import javax.swing.SortOrder; import javax.swing.SortOrder;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
@ -50,11 +46,9 @@ import javax.swing.table.TableRowSorter;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.database.motor.ThrustCurveMotorSet; import net.sf.openrocket.database.motor.ThrustCurveMotorSet;
import net.sf.openrocket.gui.components.StyledLabel; import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.StyledLabel.Style;
import net.sf.openrocket.gui.dialogs.motor.CloseableDialog; import net.sf.openrocket.gui.dialogs.motor.CloseableDialog;
import net.sf.openrocket.gui.dialogs.motor.MotorSelector; import net.sf.openrocket.gui.dialogs.motor.MotorSelector;
import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.Icons;
import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.Markers; import net.sf.openrocket.logging.Markers;
@ -69,15 +63,7 @@ import net.sf.openrocket.util.BugException;
import net.sf.openrocket.utils.MotorCorrelation; import net.sf.openrocket.utils.MotorCorrelation;
import org.jfree.chart.ChartColor; import org.jfree.chart.ChartColor;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -88,21 +74,15 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
private static final double MOTOR_SIMILARITY_THRESHOLD = 0.95; private static final double MOTOR_SIMILARITY_THRESHOLD = 0.95;
private static final int ZOOM_ICON_POSITION_NEGATIVE_X = 50;
private static final int ZOOM_ICON_POSITION_POSITIVE_Y = 12;
private static final Paint[] CURVE_COLORS = ChartColor.createDefaultPaintArray(); private static final Paint[] CURVE_COLORS = ChartColor.createDefaultPaintArray();
private static final Color NO_COMMENT_COLOR = Color.GRAY;
private static final Color WITH_COMMENT_COLOR = Color.BLACK;
private static final ThrustCurveMotorComparator MOTOR_COMPARATOR = new ThrustCurveMotorComparator(); private static final ThrustCurveMotorComparator MOTOR_COMPARATOR = new ThrustCurveMotorComparator();
private List<ThrustCurveMotorSet> database; private List<ThrustCurveMotorSet> database;
private CloseableDialog dialog = null; private CloseableDialog dialog = null;
final ThrustCurveMotorDatabaseModel model; private final ThrustCurveMotorDatabaseModel model;
private final JTable table; private final JTable table;
private final TableRowSorter<TableModel> sorter; private final TableRowSorter<TableModel> sorter;
private final MotorRowFilter rowFilter; private final MotorRowFilter rowFilter;
@ -110,33 +90,15 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
private final JCheckBox hideSimilarBox; private final JCheckBox hideSimilarBox;
private final JTextField searchField; private final JTextField searchField;
String[] searchTerms = new String[0];
private final StyledLabel diameterLabel;
private final JLabel curveSelectionLabel; private final JLabel curveSelectionLabel;
private final JComboBox curveSelectionBox; private final JComboBox curveSelectionBox;
private final DefaultComboBoxModel curveSelectionModel; private final DefaultComboBoxModel curveSelectionModel;
private final JLabel totalImpulseLabel;
private final JLabel classificationLabel;
private final JLabel avgThrustLabel;
private final JLabel maxThrustLabel;
private final JLabel burnTimeLabel;
private final JLabel launchMassLabel;
private final JLabel emptyMassLabel;
private final JLabel dataPointsLabel;
private final JLabel digestLabel;
private final JTextArea comment;
private final Font noCommentFont;
private final Font withCommentFont;
private final JFreeChart chart;
private final ChartPanel chartPanel;
private final JLabel zoomIcon;
private final JComboBox delayBox; private final JComboBox delayBox;
private final MotorInformationPanel motorInformationPanel;
private final MotorFilterPanel motorFilterPanel;
private ThrustCurveMotor selectedMotor; private ThrustCurveMotor selectedMotor;
private ThrustCurveMotorSet selectedMotorSet; private ThrustCurveMotorSet selectedMotorSet;
private double selectedDelay; private double selectedDelay;
@ -157,51 +119,126 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
super(new MigLayout("fill", "[grow][]")); super(new MigLayout("fill", "[grow][]"));
// Construct the database (adding the current motor if not in the db already) // Construct the database (adding the current motor if not in the db already)
List<ThrustCurveMotorSet> db; database = Application.getThrustCurveMotorSetDatabase().getMotorSets();
db = Application.getThrustCurveMotorSetDatabase().getMotorSets();
database = db;
model = new ThrustCurveMotorDatabaseModel(database); model = new ThrustCurveMotorDatabaseModel(database);
rowFilter = new MotorRowFilter(model); rowFilter = new MotorRowFilter(model);
motorInformationPanel = new MotorInformationPanel();
//// MotorFilter
{
// Find all the manufacturers:
Set<Manufacturer> allManufacturers = new HashSet<Manufacturer>();
for (ThrustCurveMotorSet s : database) {
allManufacturers.add(s.getManufacturer());
}
motorFilterPanel = new MotorFilterPanel(allManufacturers, rowFilter) {
@Override
public void onSelectionChanged() {
sorter.sort();
scrollSelectionVisible();
}
};
}
//// GUI //// GUI
JPanel panel = new JPanel(new MigLayout("fill","[][grow][]"));
JPanel panel;
JLabel label;
panel = new JPanel(new MigLayout("fill"));
this.add(panel, "grow"); this.add(panel, "grow");
//// Select thrust curve:
{
curveSelectionLabel = new JLabel(trans.get("TCMotorSelPan.lbl.Selectthrustcurve"));
panel.add(curveSelectionLabel);
curveSelectionModel = new DefaultComboBoxModel();
curveSelectionBox = new JComboBox(curveSelectionModel);
curveSelectionBox.setRenderer(new CurveSelectionRenderer(curveSelectionBox.getRenderer()));
curveSelectionBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Object value = curveSelectionBox.getSelectedItem();
if (value != null) {
select(((MotorHolder) value).getMotor());
}
}
});
panel.add(curveSelectionBox, "growx");
// Selection label final JPopupMenu popup = new JPopupMenu();
//// Select rocket motor: popup.add( motorInformationPanel );
label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Selrocketmotor"), Style.BOLD); JButton showDetailsButton = new JButton(trans.get("TCMotorSelPan.btn.details"));
panel.add(label, "spanx, wrap para"); showDetailsButton.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
panel.add(showDetailsButton, "gapleft para, wrap");
}
// Ejection charge delay:
{
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Ejectionchargedelay")));
delayBox = new JComboBox();
delayBox.setEditable(true);
delayBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource();
String sel = (String) cb.getSelectedItem();
//// None
if (sel.equalsIgnoreCase(trans.get("TCMotorSelPan.equalsIgnoreCase.None"))) {
selectedDelay = Motor.PLUGGED;
} else {
try {
selectedDelay = Double.parseDouble(sel);
} catch (NumberFormatException ignore) {
}
}
setDelays(false);
}
});
panel.add(delayBox, "growx");
//// (Number of seconds or \"None\")
panel.add(new StyledLabel(trans.get("TCMotorSelPan.lbl.NumberofsecondsorNone"), -3), "wrap para");
setDelays(false);
}
// Search field // Search field
{
//// Search: //// Search:
label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Search")); StyledLabel label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Search"));
panel.add(label, "split"); panel.add(label);
searchField = new JTextField(); searchField = new JTextField();
searchField.getDocument().addDocumentListener(new DocumentListener() { searchField.getDocument().addDocumentListener(new DocumentListener() {
@Override @Override
public void changedUpdate(DocumentEvent e) { public void changedUpdate(DocumentEvent e) {
update(); update();
} }
@Override @Override
public void insertUpdate(DocumentEvent e) { public void insertUpdate(DocumentEvent e) {
update(); update();
} }
@Override @Override
public void removeUpdate(DocumentEvent e) { public void removeUpdate(DocumentEvent e) {
update(); update();
} }
private void update() { private void update() {
String text = searchField.getText().trim(); String text = searchField.getText().trim();
String[] split = text.split("\\s+"); String[] split = text.split("\\s+");
@ -210,60 +247,13 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
scrollSelectionVisible(); scrollSelectionVisible();
} }
}); });
panel.add(searchField, "growx"); panel.add(searchField, "span, growx, wrap");
}
//// Motor selection table
{ {
// Find all the manufacturers:
Set<Manufacturer> allManufacturers = new HashSet<Manufacturer>();
for (ThrustCurveMotorSet s : database) {
allManufacturers.add(s.getManufacturer());
}
final MotorFilterPopupMenu popup = new MotorFilterPopupMenu(allManufacturers, rowFilter) {
@Override
public void onSelectionChanged() {
sorter.sort();
scrollSelectionVisible();
}
};
JButton manuFilter = new JButton(trans.get("TCMotorSelPan.btn.filter"));
manuFilter.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
panel.add(manuFilter, "gapleft para, wrap para");
}
// Motor selection table
table = new JTable(model); table = new JTable(model);
// Set comparators and widths // Set comparators and widths
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
sorter = new TableRowSorter<TableModel>(model); sorter = new TableRowSorter<TableModel>(model);
@ -313,11 +303,13 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
} }
}); });
JScrollPane scrollpane = new JScrollPane(); JScrollPane scrollpane = new JScrollPane();
scrollpane.setViewportView(table); scrollpane.setViewportView(table);
panel.add(scrollpane, "grow, width :500:, height :300:, spanx, wrap para"); panel.add(scrollpane, "grow, width :500:, height :300:, spanx, wrap para");
}
//// Hide used motor files
{ {
final JCheckBox hideUsedBox = new JCheckBox(trans.get("TCMotorSelPan.checkbox.hideUsed")); final JCheckBox hideUsedBox = new JCheckBox(trans.get("TCMotorSelPan.checkbox.hideUsed"));
GUIUtil.changeFontSize(hideUsedBox, -1); GUIUtil.changeFontSize(hideUsedBox, -1);
@ -332,9 +324,8 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
panel.add(hideUsedBox, "gapleft para, spanx, growx, wrap para"); panel.add(hideUsedBox, "gapleft para, spanx, growx, wrap para");
} }
scrollSelectionVisible();
//// Hide very similar thrust curves //// Hide very similar thrust curves
{
hideSimilarBox = new JCheckBox(trans.get("TCMotorSelPan.checkbox.hideSimilar")); hideSimilarBox = new JCheckBox(trans.get("TCMotorSelPan.checkbox.hideSimilar"));
GUIUtil.changeFontSize(hideSimilarBox, -1); GUIUtil.changeFontSize(hideSimilarBox, -1);
hideSimilarBox.setSelected(Application.getPreferences().getBoolean(net.sf.openrocket.startup.Preferences.MOTOR_HIDE_SIMILAR, true)); hideSimilarBox.setSelected(Application.getPreferences().getBoolean(net.sf.openrocket.startup.Preferences.MOTOR_HIDE_SIMILAR, true));
@ -346,200 +337,20 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
} }
}); });
panel.add(hideSimilarBox, "gapleft para, spanx, growx, wrap para"); panel.add(hideSimilarBox, "gapleft para, spanx, growx, wrap para");
}
// Motor mount diameter label
//// Motor mount diameter:
diameterLabel = new StyledLabel();
panel.add(label, "gapright 30lp, spanx, split");
// Vertical split // Vertical split
this.add(panel, "grow"); this.add(panel, "grow");
this.add(new JSeparator(JSeparator.VERTICAL), "growy, gap para para"); this.add(new JSeparator(JSeparator.VERTICAL), "growy, gap para para");
panel = new JPanel(new MigLayout("fill"));
JTabbedPane rightSide = new JTabbedPane();
rightSide.add(trans.get("TCMotorSelPan.btn.filter"), motorFilterPanel);
rightSide.add(trans.get("TCMotorSelPan.btn.details"), motorInformationPanel);
this.add(rightSide);
// Thrust curve selection
//// Select thrust curve:
curveSelectionLabel = new JLabel(trans.get("TCMotorSelPan.lbl.Selectthrustcurve"));
panel.add(curveSelectionLabel);
curveSelectionModel = new DefaultComboBoxModel();
curveSelectionBox = new JComboBox(curveSelectionModel);
curveSelectionBox.setRenderer(new CurveSelectionRenderer(curveSelectionBox.getRenderer()));
curveSelectionBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Object value = curveSelectionBox.getSelectedItem();
if (value != null) {
select(((MotorHolder) value).getMotor());
}
}
});
panel.add(curveSelectionBox, "growx, wrap para");
// Ejection charge delay:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Ejectionchargedelay")));
delayBox = new JComboBox();
delayBox.setEditable(true);
delayBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource();
String sel = (String) cb.getSelectedItem();
//// None
if (sel.equalsIgnoreCase(trans.get("TCMotorSelPan.equalsIgnoreCase.None"))) {
selectedDelay = Motor.PLUGGED;
} else {
try {
selectedDelay = Double.parseDouble(sel);
} catch (NumberFormatException ignore) {
}
}
setDelays(false);
}
});
panel.add(delayBox, "growx, wrap rel");
//// (Number of seconds or \"None\")
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, "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")));
avgThrustLabel = new JLabel();
panel.add(avgThrustLabel, "wrap");
//// Max. thrust:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Maxthrust")));
maxThrustLabel = new JLabel();
panel.add(maxThrustLabel, "wrap");
//// Burn time:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Burntime")));
burnTimeLabel = new JLabel();
panel.add(burnTimeLabel, "wrap");
//// Launch mass:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Launchmass")));
launchMassLabel = new JLabel();
panel.add(launchMassLabel, "wrap");
//// Empty mass:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Emptymass")));
emptyMassLabel = new JLabel();
panel.add(emptyMassLabel, "wrap");
//// Data points:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Datapoints")));
dataPointsLabel = new JLabel();
panel.add(dataPointsLabel, "wrap para");
if (System.getProperty("openrocket.debug.motordigest") != null) {
//// Digest:
panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Digest")));
digestLabel = new JLabel();
panel.add(digestLabel, "w :300:, wrap para");
} else {
digestLabel = null;
}
comment = new JTextArea(5, 5);
GUIUtil.changeFontSize(comment, -2);
withCommentFont = comment.getFont();
noCommentFont = withCommentFont.deriveFont(Font.ITALIC);
comment.setLineWrap(true);
comment.setWrapStyleWord(true);
comment.setEditable(false);
scrollpane = new JScrollPane(comment);
panel.add(scrollpane, "spanx, growx, wrap para");
// Thrust curve plot
chart = ChartFactory.createXYLineChart(
null, // title
null, // xAxisLabel
null, // yAxisLabel
null, // dataset
PlotOrientation.VERTICAL,
false, // legend
false, // tooltips
false // urls
);
// Add the data and formatting to the plot
XYPlot plot = chart.getXYPlot();
changeLabelFont(plot.getRangeAxis(), -2);
changeLabelFont(plot.getDomainAxis(), -2);
//// Thrust curve:
chart.setTitle(new TextTitle(trans.get("TCMotorSelPan.title.Thrustcurve"), this.getFont()));
chart.setBackgroundPaint(this.getBackground());
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
chartPanel = new ChartPanel(chart,
false, // properties
false, // save
false, // print
false, // zoom
false); // tooltips
chartPanel.setMouseZoomable(false);
chartPanel.setPopupMenu(null);
chartPanel.setMouseWheelEnabled(false);
chartPanel.setRangeZoomable(false);
chartPanel.setDomainZoomable(false);
chartPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
chartPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (selectedMotor == null || selectedMotorSet == null)
return;
if (e.getButton() == MouseEvent.BUTTON1) {
// Open plot dialog
List<ThrustCurveMotor> motors = getFilteredCurves();
ThrustCurveMotorPlotDialog plotDialog = new ThrustCurveMotorPlotDialog(motors,
motors.indexOf(selectedMotor),
SwingUtilities.getWindowAncestor(ThrustCurveMotorSelectionPanel.this));
plotDialog.setVisible(true);
}
}
});
JLayeredPane layer = new CustomLayeredPane();
layer.setBorder(BorderFactory.createLineBorder(Color.BLUE));
layer.add(chartPanel, (Integer) 0);
zoomIcon = new JLabel(Icons.ZOOM_IN);
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");
// Update the panel data // Update the panel data
scrollSelectionVisible();
updateData(); updateData();
setDelays(false); setDelays(false);
@ -548,6 +359,10 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
public void setMotorMountAndConfig( MotorMount mount, String currentConfig ) { public void setMotorMountAndConfig( MotorMount mount, String currentConfig ) {
double diameter = 0; double diameter = 0;
if ( mount != null ) {
diameter = mount.getMotorMountDiameter();
}
if (currentConfig != null && mount != null) { if (currentConfig != null && mount != null) {
MotorConfiguration motorConf = mount.getMotorConfiguration().get(currentConfig); MotorConfiguration motorConf = mount.getMotorConfiguration().get(currentConfig);
selectedMotor = (ThrustCurveMotor) motorConf.getMotor(); selectedMotor = (ThrustCurveMotor) motorConf.getMotor();
@ -576,10 +391,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
updateData(); updateData();
setDelays(true); setDelays(true);
diameterLabel.setText(trans.get("TCMotorSelPan.lbl.Motormountdia") + " " + motorFilterPanel.setMotorMount(mount);
UnitGroup.UNITS_MOTOR_DIMENSIONS.getDefaultUnit().toStringUnit(0));
rowFilter.setMotorMount(mount);
scrollSelectionVisible(); scrollSelectionVisible();
} }
@ -629,13 +441,6 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
private void changeLabelFont(ValueAxis axis, float size) {
Font font = axis.getTickLabelFont();
font = font.deriveFont(font.getSize2D() + size);
axis.setTickLabelFont(font);
}
/** /**
* Called when a different motor is selected from within the panel. * Called when a different motor is selected from within the panel.
*/ */
@ -666,30 +471,14 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
curveSelectionModel.removeAllElements(); curveSelectionModel.removeAllElements();
curveSelectionBox.setEnabled(false); curveSelectionBox.setEnabled(false);
curveSelectionLabel.setEnabled(false); curveSelectionLabel.setEnabled(false);
totalImpulseLabel.setText(""); motorInformationPanel.clearData();
totalImpulseLabel.setToolTipText(null);
classificationLabel.setText("");
classificationLabel.setToolTipText(null);
avgThrustLabel.setText("");
maxThrustLabel.setText("");
burnTimeLabel.setText("");
launchMassLabel.setText("");
emptyMassLabel.setText("");
dataPointsLabel.setText("");
if (digestLabel != null) {
digestLabel.setText("");
}
setComment("");
chart.getXYPlot().setDataset(new XYSeriesCollection());
return; return;
} }
// Check which thrust curves to display // Check which thrust curves to display
List<ThrustCurveMotor> motors = getFilteredCurves(); List<ThrustCurveMotor> motors = getFilteredCurves();
final int index = motors.indexOf(selectedMotor); final int index = motors.indexOf(selectedMotor);
// Update the thrust curve selection box // Update the thrust curve selection box
curveSelectionModel.removeAllElements(); curveSelectionModel.removeAllElements();
for (int i = 0; i < motors.size(); i++) { for (int i = 0; i < motors.size(); i++) {
@ -705,60 +494,11 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
curveSelectionLabel.setEnabled(false); curveSelectionLabel.setEnabled(false);
} }
motorInformationPanel.updateData(motors, selectedMotor);
// Update thrust curve data
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.getMaxThrustEstimate()));
burnTimeLabel.setText(UnitGroup.UNITS_SHORT_TIME.getDefaultUnit().toStringUnit(
selectedMotor.getBurnTimeEstimate()));
launchMassLabel.setText(UnitGroup.UNITS_MASS.getDefaultUnit().toStringUnit(
selectedMotor.getLaunchCG().weight));
emptyMassLabel.setText(UnitGroup.UNITS_MASS.getDefaultUnit().toStringUnit(
selectedMotor.getEmptyCG().weight));
dataPointsLabel.setText("" + (selectedMotor.getTimePoints().length - 1));
if (digestLabel != null) {
digestLabel.setText(selectedMotor.getDigest());
} }
setComment(selectedMotor.getDescription()); List<ThrustCurveMotor> getFilteredCurves() {
// Update the plot
XYPlot plot = chart.getXYPlot();
XYSeriesCollection dataset = new XYSeriesCollection();
for (int i = 0; i < motors.size(); i++) {
ThrustCurveMotor m = motors.get(i);
//// Thrust
XYSeries series = new XYSeries(trans.get("TCMotorSelPan.title.Thrust") + " (" + i + ")");
double[] time = m.getTimePoints();
double[] thrust = m.getThrustPoints();
for (int j = 0; j < time.length; j++) {
series.add(time[j], thrust[j]);
}
dataset.addSeries(series);
boolean selected = (i == index);
plot.getRenderer().setSeriesStroke(i, new BasicStroke(selected ? 3 : 1));
plot.getRenderer().setSeriesPaint(i, getColor(i));
}
plot.setDataset(dataset);
}
private List<ThrustCurveMotor> getFilteredCurves() {
List<ThrustCurveMotor> motors = selectedMotorSet.getMotors(); List<ThrustCurveMotor> motors = selectedMotorSet.getMotors();
if (hideSimilarBox.isSelected()) { if (hideSimilarBox.isSelected()) {
List<ThrustCurveMotor> filtered = new ArrayList<ThrustCurveMotor>(motors.size()); List<ThrustCurveMotor> filtered = new ArrayList<ThrustCurveMotor>(motors.size());
@ -784,21 +524,6 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
} }
private void setComment(String s) {
s = s.trim();
if (s.length() == 0) {
//// No description available.
comment.setText(trans.get("TCMotorSelPan.noDescription"));
comment.setFont(noCommentFont);
comment.setForeground(NO_COMMENT_COLOR);
} else {
comment.setText(s);
comment.setFont(withCommentFont);
comment.setForeground(WITH_COMMENT_COLOR);
}
comment.setCaretPosition(0);
}
private void scrollSelectionVisible() { private void scrollSelectionVisible() {
if (selectedMotorSet != null) { if (selectedMotorSet != null) {
int index = table.convertRowIndexToView(model.getIndex(selectedMotorSet)); int index = table.convertRowIndexToView(model.getIndex(selectedMotorSet));
@ -920,9 +645,6 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
} }
} }
////////////////////// //////////////////////
@ -950,18 +672,4 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
} }
/**
* Custom layered pane that sets the bounds of the components on every layout.
*/
public class CustomLayeredPane extends JLayeredPane {
@Override
public void doLayout() {
synchronized (getTreeLock()) {
int w = getWidth();
int h = getHeight();
chartPanel.setBounds(0, 0, w, h);
zoomIcon.setBounds(w - ZOOM_ICON_POSITION_NEGATIVE_X, ZOOM_ICON_POSITION_POSITIVE_Y, 50, 50);
}
}
}
} }