Make the ComponentPresetChooserDialog more forgiving about presets which are missing...
[debian/openrocket] / core / src / net / sf / openrocket / gui / dialogs / preset / ComponentPresetChooserDialog.java
1 package net.sf.openrocket.gui.dialogs.preset;
2
3
4 import java.awt.Dialog;
5 import java.awt.Window;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.util.List;
9
10 import javax.swing.JButton;
11 import javax.swing.JDialog;
12 import javax.swing.JLabel;
13 import javax.swing.JPanel;
14 import javax.swing.JScrollPane;
15 import javax.swing.JTable;
16 import javax.swing.JTextField;
17 import javax.swing.ListSelectionModel;
18 import javax.swing.RowFilter;
19 import javax.swing.event.DocumentEvent;
20 import javax.swing.event.DocumentListener;
21 import javax.swing.table.TableModel;
22 import javax.swing.table.TableRowSorter;
23
24 import net.miginfocom.swing.MigLayout;
25 import net.sf.openrocket.gui.adaptors.Column;
26 import net.sf.openrocket.gui.adaptors.ColumnTableModel;
27 import net.sf.openrocket.gui.util.GUIUtil;
28 import net.sf.openrocket.l10n.Translator;
29 import net.sf.openrocket.preset.ComponentPreset;
30 import net.sf.openrocket.preset.TypedKey;
31 import net.sf.openrocket.rocketcomponent.RocketComponent;
32 import net.sf.openrocket.startup.Application;
33 import net.sf.openrocket.unit.Value;
34
35 public class ComponentPresetChooserDialog extends JDialog {
36         
37         private static final Translator trans = Application.getTranslator();
38         
39         private final JTable componentSelectionTable;
40         private final TableRowSorter<TableModel> sorter;
41         private final JTextField filterText;
42         
43         private final List<ComponentPreset> presets;
44         
45         private boolean okClicked = false;
46         
47         
48         public ComponentPresetChooserDialog(Window owner, RocketComponent component) {
49                 super(owner, trans.get("title"), Dialog.ModalityType.APPLICATION_MODAL);
50                 
51                 final TypedKey<?>[] columnKeys = component.getPresetType().getDisplayedColumns();
52                 
53                 presets = Application.getComponentPresetDao().listForType(component.getPresetType());
54                 
55                 JPanel panel = new JPanel(new MigLayout("fill"));
56                 JLabel filterLabel = new JLabel(trans.get("ComponentPresetChooserDialog.filter.label"));
57                 panel.add(filterLabel);
58                 filterText = new JTextField(15);
59                 panel.add(filterText,"growx, growy 0, wrap");
60                 filterText.getDocument().addDocumentListener(new DocumentListener() {
61                         @Override
62                         public void changedUpdate(DocumentEvent e) {
63                                 newFilter(filterText.getText());
64                         }
65                         @Override
66                         public void insertUpdate(DocumentEvent e) {
67                                 newFilter(filterText.getText());
68                         }
69                         @Override
70                         public void removeUpdate(DocumentEvent e) {
71                                 newFilter(filterText.getText());
72                         }
73                 });
74                 
75                 final Column[] columns = new Column[columnKeys.length+1];
76                 
77                 columns[0] = new Column(trans.get("table.column.Favorite") ) {
78                         @Override
79                         public Object getValueAt(int row) {
80                                 return Boolean.valueOf(ComponentPresetChooserDialog.this.presets.get(row).isFavorite());
81                         }
82                         
83                         @Override
84                         public void setValueAt(int row, Object value) {
85                                 Application.getComponentPresetDao().setFavorite(ComponentPresetChooserDialog.this.presets.get(row), (Boolean) value);
86                         }
87
88                         @Override
89                         public Class<?> getColumnClass() {
90                                 return Boolean.class;
91                         }
92                         
93                 };
94                 for (int i = 0; i < columnKeys.length; i++) {
95                         final TypedKey<?> key = columnKeys[i];
96                         columns[i+1] = new Column(trans.get("table.column." + columnKeys[i].getName())) {
97                                 @Override
98                                 public Object getValueAt(int row) {
99                                         ComponentPreset preset = ComponentPresetChooserDialog.this.presets.get(row);
100                                         if ( ! preset.has(key) ) {
101                                                 return null;
102                                         }
103                                         Object value = preset.get(key);
104                                         if (key.getType() == Double.class && key.getUnitGroup() != null) {
105                                                 return new Value( (Double) value, key.getUnitGroup() );
106                                         } else {
107                                                 return value;
108                                         }
109                                 }
110                         };
111                 }
112                 
113                 ColumnTableModel tableModel = new ColumnTableModel(columns) {
114                         @Override
115                         public int getRowCount() {
116                                 return ComponentPresetChooserDialog.this.presets.size();
117                         }
118
119                         @Override
120                         public boolean isCellEditable(int rowIndex, int columnIndex) {
121                                 return columnIndex == 0;
122                         }
123                         
124                 };
125                 
126                 componentSelectionTable = new JTable( tableModel );
127                 
128                 componentSelectionTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
129
130                 sorter = new TableRowSorter<TableModel>(tableModel);
131                 componentSelectionTable.setRowSorter(sorter);
132
133                 JScrollPane scrollpane = new JScrollPane();
134                 scrollpane.setViewportView(componentSelectionTable);
135                 panel.add(scrollpane, "grow, width :500:, height :300:, spanx, wrap para");
136
137                 
138                 // OK / Cancel buttons
139                 JButton okButton = new JButton(trans.get("dlg.but.ok"));
140                 okButton.addActionListener(new ActionListener() {
141                         @Override
142                         public void actionPerformed(ActionEvent e) {
143                                 close(true);
144                         }
145                 });
146                 panel.add(okButton, "tag ok, spanx, split");
147                 
148                 //// Cancel button
149                 JButton cancelButton = new JButton(trans.get("dlg.but.cancel"));
150                 cancelButton.addActionListener(new ActionListener() {
151                         @Override
152                         public void actionPerformed(ActionEvent e) {
153                                 close(false);
154                         }
155                 });
156                 panel.add(cancelButton, "tag cancel");
157                 
158                 this.add(panel);
159                 
160                 this.setModal(true);
161                 this.pack();
162                 this.setLocationByPlatform(true);
163                 GUIUtil.setDisposableDialogOptions(this, okButton);
164                 
165                 //JComponent focus = selectionPanel.getDefaultFocus();
166                 //if (focus != null) {
167                 //      focus.grabFocus();
168                 //}
169                 
170                 // Set the closeable dialog after all initialization
171                 //selectionPanel.setCloseableDialog(this);
172         }
173         
174         /**
175          * Return the motor selected by this chooser dialog, or <code>null</code> if the selection has been aborted.
176          * 
177          * @return      the selected motor, or <code>null</code> if no motor has been selected or the selection was canceled.
178          */
179         public ComponentPreset getSelectedComponentPreset() {
180                 if (!okClicked)
181                         return null;
182                 int row = componentSelectionTable.getSelectedRow();
183                 row = componentSelectionTable.convertRowIndexToModel(row);
184                 return presets.get(row);
185         }
186         
187         public void close(boolean ok) {
188                 okClicked = ok;
189                 this.setVisible(false);
190         }
191         
192         private void newFilter(String regex) {
193                 RowFilter<TableModel,Object> filter = null;
194                 try {
195                         // The "(?iu)" magic turns on case insensitivity with unicode chars
196                         filter = RowFilter.regexFilter("(?iu)"+regex);
197                 } catch ( java.util.regex.PatternSyntaxException e ) {
198                         // FIXME - do we want to remove the filter?
199                         return;
200                 }
201                 sorter.setRowFilter(filter);
202         }
203 }