Added filter check boxes to limit the displayed components based on fitting with...
authorkruland2607 <kruland2607@180e2498-e6e9-4542-8430-84ac67f01cd8>
Mon, 16 Apr 2012 19:17:17 +0000 (19:17 +0000)
committerkruland2607 <kruland2607@180e2498-e6e9-4542-8430-84ac67f01cd8>
Mon, 16 Apr 2012 19:17:17 +0000 (19:17 +0000)
git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@560 180e2498-e6e9-4542-8430-84ac67f01cd8

core/resources/l10n/messages.properties
core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java
core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetRowFilter.java [new file with mode: 0644]

index 501aa5559c3b63809df881a895ec48aac55e9cdb..43c4beaef08f03871cc231ee4b5ee145e70519e4 100644 (file)
@@ -1591,6 +1591,8 @@ PresetModel.lbl.database = From database...
 ! Component Preset Chooser Dialog
 ComponentPresetChooserDialog.title = Choose component preset
 ComponentPresetChooserDialog.filter.label = Filter:
+ComponentPresetChooserDialog.checkbox.filterAftDiameter = Match aft diameter
+ComponentPresetChooserDialog.checkbox.filterForeDiameter = Match fore diameter
 table.column.Favorite = Favorite
 table.column.Manufacturer = Manufacturer
 table.column.PartNo = Part Number
index c6a917f6d8218e97f169c09fe001a0d261210632..c2a6ccb0c9890670b5853a843ef5f8c68510aa05 100644 (file)
@@ -5,9 +5,13 @@ import java.awt.Dialog;
 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;
@@ -28,7 +32,9 @@ import net.sf.openrocket.gui.util.GUIUtil;
 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;
 
@@ -36,10 +42,21 @@ public class ComponentPresetChooserDialog extends JDialog {
        
        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;
@@ -47,31 +64,15 @@ public class ComponentPresetChooserDialog extends JDialog {
        
        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") ) {
@@ -91,9 +92,18 @@ public class ComponentPresetChooserDialog extends JDialog {
                        }
                        
                };
+
                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);
@@ -110,6 +120,18 @@ public class ComponentPresetChooserDialog extends JDialog {
                        };
                }
                
+               /*
+                * 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() {
@@ -123,6 +145,66 @@ public class ComponentPresetChooserDialog extends JDialog {
                        
                };
                
+
+               /*
+                * 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);
@@ -189,15 +271,54 @@ public class ComponentPresetChooserDialog extends JDialog {
                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) );
        }
 }
diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetRowFilter.java b/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetRowFilter.java
new file mode 100644 (file)
index 0000000..78eadda
--- /dev/null
@@ -0,0 +1,34 @@
+package net.sf.openrocket.gui.dialogs.preset;
+
+import javax.swing.RowFilter;
+import javax.swing.table.TableModel;
+
+import net.sf.openrocket.unit.Value;
+
+public class ComponentPresetRowFilter extends RowFilter<TableModel, Object> {
+       
+       private final double value;
+       private final int column;
+       // FIXME - what should epsilon be?
+       private final double epsilon = .0002;
+       
+       ComponentPresetRowFilter( double value, int column ) {
+               this.value = value;
+               this.column = column;
+       }
+
+       @Override
+       public boolean include( RowFilter.Entry<? extends TableModel, ? extends Object> entry) {
+               Object o = entry.getValue(column);
+               if ( o instanceof Value ) {
+                       Value v = (Value)o;
+                       return Math.abs( value - v.getValue() ) < epsilon;
+               }
+               if ( o instanceof Double ) {
+                       Double d = (Double) o;
+                       return Math.abs( value - d ) < epsilon;
+               }
+               return true;
+       }
+
+}