X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=core%2Fsrc%2Fnet%2Fsf%2Fopenrocket%2Fgui%2Fdialogs%2Fpreset%2FComponentPresetChooserDialog.java;h=9efa3675e7a789c022b9ccfc809516ba02b46d41;hb=4095cb0dd61a75b7b6b0bd811f8e803af5b27919;hp=c2a6ccb0c9890670b5853a843ef5f8c68510aa05;hpb=7f8091bf1080836f45fa6740e80be1e27e2218f8;p=debian%2Fopenrocket diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java b/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java index c2a6ccb0..9efa3675 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java +++ b/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java @@ -8,6 +8,7 @@ import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import javax.swing.JButton; @@ -16,39 +17,39 @@ import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; -import javax.swing.JTable; import javax.swing.JTextField; -import javax.swing.ListSelectionModel; import javax.swing.RowFilter; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import javax.swing.table.TableColumn; import javax.swing.table.TableModel; -import javax.swing.table.TableRowSorter; import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.gui.adaptors.Column; -import net.sf.openrocket.gui.adaptors.ColumnTableModel; 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; +/** + * Dialog shown for selecting a preset component. + */ public class ComponentPresetChooserDialog extends JDialog { private static final Translator trans = Application.getTranslator(); private final RocketComponent component; - private final JTable componentSelectionTable; - private final TableRowSorter sorter; - private final JTextField filterText; - private final JCheckBox foreDiameterFilterCheckBox; - private final JCheckBox aftDiameterFilterCheckBox; + private ComponentPresetTable componentSelectionTable; + private JTextField filterText; + private JCheckBox foreDiameterFilterCheckBox; + private JCheckBox aftDiameterFilterCheckBox; + + private ComponentPresetRowFilter foreDiameterFilter; + private ComponentPresetRowFilter aftDiameterFilter; + /* * outerDiamtereColumnIndex is the index of the column associated with the OUTER_DIAMETER @@ -56,8 +57,9 @@ public class ComponentPresetChooserDialog extends JDialog { */ int aftDiameterColumnIndex = -1; int foreDiameterColumnIndex = -1; - - private final List presets; + + private List presets; + private ComponentPreset.Type presetType; private boolean okClicked = false; @@ -65,157 +67,78 @@ public class ComponentPresetChooserDialog extends JDialog { public ComponentPresetChooserDialog(Window owner, RocketComponent component) { super(owner, trans.get("title"), Dialog.ModalityType.APPLICATION_MODAL); this.component = component; + this.presetType = component.getPresetType(); + this.presets = Application.getComponentPresetDao().listForType(component.getPresetType()); - final TypedKey[] columnKeys = component.getPresetType().getDisplayedColumns(); - - presets = Application.getComponentPresetDao().listForType(component.getPresetType()); - - /* - * Set up the Column Table model - */ - final Column[] columns = new Column[columnKeys.length+1]; + List> displayedColumnKeys = Arrays.asList(component.getPresetType().getDisplayedColumns()); - columns[0] = new Column(trans.get("table.column.Favorite") ) { - @Override - public Object getValueAt(int row) { - return Boolean.valueOf(ComponentPresetChooserDialog.this.presets.get(row).isFavorite()); - } - - @Override - public void setValueAt(int row, Object value) { - Application.getComponentPresetDao().setFavorite(ComponentPresetChooserDialog.this.presets.get(row), (Boolean) value); - } - - @Override - public Class getColumnClass() { - return Boolean.class; - } - - }; - - for (int i = 0; i < columnKeys.length; i++) { - final TypedKey key = columnKeys[i]; - 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); - if ( ! preset.has(key) ) { - return null; - } - Object value = preset.get(key); - if (key.getType() == Double.class && key.getUnitGroup() != null) { - return new Value( (Double) value, key.getUnitGroup() ); - } else { - return value; - } + { + final List> columnKeys = ComponentPreset.ORDERED_KEY_LIST; + int i = 0; // We start at 0 but use preincrement because the first column is favorite. + for (final TypedKey key : columnKeys) { + // Note the increment early in the loop. This really means that initial loop i=1 + // we do it here so the continue below doesn't mess up the counting. + i++; + // Don't allow the matching filters if the column is not part of the default set for + // this kind of preset. + if (!displayedColumnKeys.contains(key)) { + continue; + } + if (key == ComponentPreset.OUTER_DIAMETER || key == ComponentPreset.AFT_OUTER_DIAMETER) { + aftDiameterColumnIndex = i; + } + if (key == ComponentPreset.OUTER_DIAMETER || key == ComponentPreset.FORE_OUTER_DIAMETER) { + foreDiameterColumnIndex = i; } - }; + } } - /* - * 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() { - return ComponentPresetChooserDialog.this.presets.size(); - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return columnIndex == 0; - } - - }; + JPanel panel = new JPanel(new MigLayout("fill, ins para")); - /* * Add filter by text. */ - JPanel panel = new JPanel(new MigLayout("fill")); + JPanel sub = new JPanel(new MigLayout("fill, ins 0")); JLabel filterLabel = new JLabel(trans.get("ComponentPresetChooserDialog.filter.label")); - panel.add(filterLabel); - filterText = new JTextField(15); - panel.add(filterText,"growx, growy 0, wrap"); + sub.add(filterLabel, "gapright para"); + + filterText = new JTextField(); + sub.add(filterText, "growx"); 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); - } + panel.add(sub, "growx, ay 0, gapright para"); - /* - * 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 ); + panel.add(getFilterCheckboxes(), "wrap para"); + + componentSelectionTable = new ComponentPresetTable(presetType, presets, displayedColumnKeys); + // GUIUtil.setAutomaticColumnTableWidths(componentSelectionTable, 20); + int w = componentSelectionTable.getRowHeight() + 4; + TableColumn tc = componentSelectionTable.getColumnModel().getColumn(0); + tc.setPreferredWidth(w); + tc.setMaxWidth(w); + tc.setMinWidth(w); - componentSelectionTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - sorter = new TableRowSorter(tableModel); - componentSelectionTable.setRowSorter(sorter); - JScrollPane scrollpane = new JScrollPane(); scrollpane.setViewportView(componentSelectionTable); - panel.add(scrollpane, "grow, width :500:, height :300:, spanx, wrap para"); - + panel.add(scrollpane, "grow, width 700lp, height 300lp, spanx, wrap para"); + // OK / Cancel buttons JButton okButton = new JButton(trans.get("dlg.but.ok")); @@ -239,18 +162,71 @@ public class ComponentPresetChooserDialog extends JDialog { this.add(panel); - this.setModal(true); - this.pack(); - this.setLocationByPlatform(true); + GUIUtil.rememberWindowSize(this); GUIUtil.setDisposableDialogOptions(this, okButton); + } + + + private JPanel getFilterCheckboxes() { + SymmetricComponent sc; - //JComponent focus = selectionPanel.getDefaultFocus(); - //if (focus != null) { - // focus.grabFocus(); - //} + JPanel panel = new JPanel(new MigLayout("fill, ins 0")); - // Set the closeable dialog after all initialization - //selectionPanel.setCloseableDialog(this); + /* + * Add show all compatible check box. + */ + final List compatibleTypes = component.getPresetType().getCompatibleTypes(); + final ComponentPreset.Type nativeType = component.getPresetType(); + if (compatibleTypes != null && compatibleTypes.size() > 0) { + JCheckBox showAll = new JCheckBox(); + showAll.setText(trans.get("ComponentPresetChooserDialog.checkbox.showAllCompatible")); + panel.add(showAll, "wrap"); + showAll.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (((JCheckBox) e.getItem()).isSelected()) { + presets = Application.getComponentPresetDao().listForTypes(compatibleTypes); + } else { + presets = Application.getComponentPresetDao().listForType(nativeType); + } + componentSelectionTable.updateData(presets); + } + }); + } + + /* + * Add filter by fore diameter + */ + foreDiameterFilterCheckBox = new JCheckBox(trans.get("ComponentPresetChooserDialog.checkbox.filterForeDiameter")); + sc = getPreviousSymmetricComponent(); + if (sc != null && foreDiameterColumnIndex >= 0) { + foreDiameterFilter = new ComponentPresetRowFilter(sc.getAftRadius() * 2.0, foreDiameterColumnIndex); + panel.add(foreDiameterFilterCheckBox, "wrap"); + foreDiameterFilterCheckBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + updateFilters(); + } + }); + } + + /* + * Add filter by aft diameter + */ + aftDiameterFilterCheckBox = new JCheckBox(trans.get("ComponentPresetChooserDialog.checkbox.filterAftDiameter")); + sc = getNextSymmetricComponent(); + if (sc != null && aftDiameterColumnIndex >= 0) { + aftDiameterFilter = new ComponentPresetRowFilter(sc.getForeRadius() * 2.0, aftDiameterColumnIndex); + panel.add(aftDiameterFilterCheckBox, "wrap"); + aftDiameterFilterCheckBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + updateFilters(); + } + }); + } + + return panel; } /** @@ -262,6 +238,10 @@ public class ComponentPresetChooserDialog extends JDialog { if (!okClicked) return null; int row = componentSelectionTable.getSelectedRow(); + if ( row < 0 ) { + // Nothing selected. + return null; + } row = componentSelectionTable.convertRowIndexToModel(row); return presets.get(row); } @@ -272,53 +252,47 @@ public class ComponentPresetChooserDialog extends JDialog { } private void updateFilters() { - List> filters = new ArrayList> (2); + List> filters = new ArrayList>(2); String filterTextRegex = filterText.getText(); - if ( filterTextRegex != null ) { + if (filterTextRegex != null) { try { // The "(?iu)" magic turns on case insensitivity with unicode chars - RowFilter regexFilter = RowFilter.regexFilter("(?iu)"+filterTextRegex); + RowFilter regexFilter = RowFilter.regexFilter("(?iu)" + filterTextRegex); filters.add(regexFilter); - } catch ( java.util.regex.PatternSyntaxException e ) { + } 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 outerDiameterFilter = new ComponentPresetRowFilter( nextDiameter, aftDiameterColumnIndex); - filters.add(outerDiameterFilter); + if (aftDiameterFilterCheckBox.isSelected()) { + filters.add(aftDiameterFilter); + } + if (foreDiameterFilterCheckBox.isSelected()) { + filters.add(foreDiameterFilter); + } + + componentSelectionTable.setRowFilter(RowFilter.andFilter(filters)); + } + + + private SymmetricComponent getPreviousSymmetricComponent() { + RocketComponent c = component; + while (c != null) { + c = c.getPreviousComponent(); + if (c instanceof SymmetricComponent) { + return (SymmetricComponent) c; } } - 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 outerDiameterFilter = new ComponentPresetRowFilter( previousDaimeter, foreDiameterColumnIndex); - filters.add(outerDiameterFilter); + return null; + } + + + private SymmetricComponent getNextSymmetricComponent() { + RocketComponent c = component; + while (c != null) { + c = c.getNextComponent(); + if (c instanceof SymmetricComponent) { + return (SymmetricComponent) c; } } - - sorter.setRowFilter( RowFilter.andFilter(filters) ); + return null; } }