import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
+import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.TypedKey;
+import net.sf.openrocket.rocketcomponent.InternalComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.rocketcomponent.SymmetricComponent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.Value;
private static final Translator trans = Application.getTranslator();
+ private final RocketComponent component;
+
private final JTable componentSelectionTable;
private final TableRowSorter<TableModel> sorter;
private final JTextField filterText;
+ private final JCheckBox foreDiameterFilterCheckBox;
+ private final JCheckBox aftDiameterFilterCheckBox;
+ /*
+ * outerDiamtereColumnIndex is the index of the column associated with the OUTER_DIAMETER
+ * field. This index is needed by the matchOuterDiameterCheckBox to implement filtering.
+ */
+ int aftDiameterColumnIndex = -1;
+ int foreDiameterColumnIndex = -1;
+
private final List<ComponentPreset> presets;
private boolean okClicked = false;
public ComponentPresetChooserDialog(Window owner, RocketComponent component) {
super(owner, trans.get("title"), Dialog.ModalityType.APPLICATION_MODAL);
+ this.component = component;
final TypedKey<?>[] columnKeys = component.getPresetType().getDisplayedColumns();
-
+
presets = Application.getComponentPresetDao().listForType(component.getPresetType());
-
- JPanel panel = new JPanel(new MigLayout("fill"));
- JLabel filterLabel = new JLabel(trans.get("ComponentPresetChooserDialog.filter.label"));
- panel.add(filterLabel);
- filterText = new JTextField(15);
- panel.add(filterText,"growx, growy 0, wrap");
- filterText.getDocument().addDocumentListener(new DocumentListener() {
- @Override
- public void changedUpdate(DocumentEvent e) {
- newFilter(filterText.getText());
- }
- @Override
- public void insertUpdate(DocumentEvent e) {
- newFilter(filterText.getText());
- }
- @Override
- public void removeUpdate(DocumentEvent e) {
- newFilter(filterText.getText());
- }
- });
-
+
+ /*
+ * Set up the Column Table model
+ */
final Column[] columns = new Column[columnKeys.length+1];
columns[0] = new Column(trans.get("table.column.Favorite") ) {
}
};
+
for (int i = 0; i < columnKeys.length; i++) {
final TypedKey<?> key = columnKeys[i];
- columns[i+1] = new Column(trans.get("table.column." + columnKeys[i].getName())) {
+ if ( key == ComponentPreset.OUTER_DIAMETER ) {
+ // magic +1 is because we have inserted the column for favorites above.
+ aftDiameterColumnIndex = i+1;
+ }
+ if ( key == ComponentPreset.FORE_OUTER_DIAMETER ) {
+ // magic +1 is because we have inserted the column for favorites above.
+ foreDiameterColumnIndex = i+1;
+ }
+ columns[i+1] = new Column(trans.get("table.column." + key.getName())) {
@Override
public Object getValueAt(int row) {
ComponentPreset preset = ComponentPresetChooserDialog.this.presets.get(row);
};
}
+ /*
+ * perhaps there is a better way for this.
+ *
+ * This check basically says that if a component does not have a fore diameter, use the
+ * outer_diameter when filtering. The problem this introduced is when this dialog is
+ * created for nose cones (which are aft of a body tube), you will be given the option
+ * to filter based on matching fore diameter.
+ */
+ if ( foreDiameterColumnIndex < 0 ) {
+ foreDiameterColumnIndex = aftDiameterColumnIndex;
+ }
+
ColumnTableModel tableModel = new ColumnTableModel(columns) {
@Override
public int getRowCount() {
};
+
+ /*
+ * Add filter by text.
+ */
+ JPanel panel = new JPanel(new MigLayout("fill"));
+ JLabel filterLabel = new JLabel(trans.get("ComponentPresetChooserDialog.filter.label"));
+ panel.add(filterLabel);
+ filterText = new JTextField(15);
+ panel.add(filterText,"growx, growy 0, wrap");
+ filterText.getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ updateFilters();
+ }
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ updateFilters();
+ }
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ updateFilters();
+ }
+ });
+
+ /*
+ * Add filter by fore diameter
+ */
+ foreDiameterFilterCheckBox = new JCheckBox();
+ foreDiameterFilterCheckBox.setText(trans.get("ComponentPresetChooserDialog.checkbox.filterForeDiameter"));
+ panel.add(foreDiameterFilterCheckBox, "skip, span 2");
+ foreDiameterFilterCheckBox.addItemListener( new ItemListener () {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ updateFilters();
+ }
+ });
+
+ /* hide the fore diameter filter if it is not applicable */
+ if ( foreDiameterColumnIndex < 0 || component.getPreviousComponent() == null ) {
+ foreDiameterFilterCheckBox.setVisible(false);
+ }
+
+ /*
+ * Add filter by aft diameter
+ */
+ aftDiameterFilterCheckBox = new JCheckBox();
+ aftDiameterFilterCheckBox.setText(trans.get("ComponentPresetChooserDialog.checkbox.filterAftDiameter"));
+ panel.add(aftDiameterFilterCheckBox, "skip, span 2, wrap");
+ aftDiameterFilterCheckBox.addItemListener( new ItemListener () {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ updateFilters();
+ }
+ });
+
+ /* hide the aft diameter filter if it is not applicable */
+ if ( aftDiameterColumnIndex < 0 || component.getNextComponent() == null ) {
+ aftDiameterFilterCheckBox.setVisible(false);
+ }
+
componentSelectionTable = new JTable( tableModel );
componentSelectionTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.setVisible(false);
}
- private void newFilter(String regex) {
- RowFilter<TableModel,Object> filter = null;
- try {
- // The "(?iu)" magic turns on case insensitivity with unicode chars
- filter = RowFilter.regexFilter("(?iu)"+regex);
- } catch ( java.util.regex.PatternSyntaxException e ) {
- // FIXME - do we want to remove the filter?
- return;
+ private void updateFilters() {
+ List<RowFilter<TableModel,Object>> filters = new ArrayList<RowFilter<TableModel,Object>> (2);
+ String filterTextRegex = filterText.getText();
+ if ( filterTextRegex != null ) {
+ try {
+ // The "(?iu)" magic turns on case insensitivity with unicode chars
+ RowFilter<TableModel,Object> regexFilter = RowFilter.regexFilter("(?iu)"+filterTextRegex);
+ filters.add(regexFilter);
+ } catch ( java.util.regex.PatternSyntaxException e ) {
+ }
+ }
+ if ( aftDiameterFilterCheckBox.isSelected() ) {
+ // FIXME - please verify this logic looks correct.
+ // Grab the next component.
+ // If this.component is an InternalComponent, then we want to filter the outer diameter field
+ // against the next component's inner diameter.
+ RocketComponent nextComponent = component.getNextComponent();
+ if ( nextComponent != null && nextComponent instanceof SymmetricComponent ) {
+ SymmetricComponent parent = (SymmetricComponent) nextComponent;
+ double nextDiameter;
+ if ( this.component instanceof InternalComponent ) {
+ nextDiameter = parent.getInnerRadius(0) * 2.0;
+ } else {
+ nextDiameter = parent.getForeRadius() * 2.0;
+ }
+ RowFilter<TableModel,Object> outerDiameterFilter = new ComponentPresetRowFilter( nextDiameter, aftDiameterColumnIndex);
+ filters.add(outerDiameterFilter);
+ }
}
- sorter.setRowFilter(filter);
+ if ( foreDiameterFilterCheckBox.isSelected() ) {
+ // FIXME - please verify this logic looks correct.
+ // Grab the previous component.
+ // If this.component is an InternalComponent, then we want to filter the outer diameter field
+ // against the previous component's inner diameter.
+ RocketComponent previousComponent = component.getPreviousComponent();
+ if ( previousComponent != null && previousComponent instanceof SymmetricComponent ) {
+ SymmetricComponent parent = (SymmetricComponent) previousComponent;
+ double previousDaimeter;
+ if ( this.component instanceof InternalComponent ) {
+ previousDaimeter = parent.getInnerRadius(parent.getLength()) * 2.0;
+ } else {
+ previousDaimeter = parent.getAftRadius() * 2.0;
+ }
+ RowFilter<TableModel,Object> outerDiameterFilter = new ComponentPresetRowFilter( previousDaimeter, foreDiameterColumnIndex);
+ filters.add(outerDiameterFilter);
+ }
+ }
+
+ sorter.setRowFilter( RowFilter.andFilter(filters) );
}
}