Made the ComponentPresetChooserDialog much more cool by reworking the table. User...
[debian/openrocket] / core / src / net / sf / openrocket / gui / dialogs / preset / ComponentPresetTable.java
1 package net.sf.openrocket.gui.dialogs.preset;
2
3 import java.awt.event.ItemEvent;
4 import java.awt.event.ItemListener;
5 import java.awt.event.MouseAdapter;
6 import java.awt.event.MouseEvent;
7 import java.util.ArrayList;
8 import java.util.Collections;
9 import java.util.List;
10
11 import javax.swing.JCheckBoxMenuItem;
12 import javax.swing.JMenu;
13 import javax.swing.JMenuItem;
14 import javax.swing.JPopupMenu;
15 import javax.swing.JTable;
16 import javax.swing.ListSelectionModel;
17 import javax.swing.RowFilter;
18 import javax.swing.RowSorter.SortKey;
19 import javax.swing.SortOrder;
20 import javax.swing.event.ListSelectionEvent;
21 import javax.swing.table.AbstractTableModel;
22 import javax.swing.table.JTableHeader;
23 import javax.swing.table.TableColumn;
24 import javax.swing.table.TableModel;
25 import javax.swing.table.TableRowSorter;
26
27 import net.sf.openrocket.l10n.Translator;
28 import net.sf.openrocket.preset.ComponentPreset;
29 import net.sf.openrocket.preset.TypedKey;
30 import net.sf.openrocket.startup.Application;
31 import net.sf.openrocket.unit.Unit;
32 import net.sf.openrocket.unit.UnitGroup;
33
34 public class ComponentPresetTable extends JTable {
35
36         private static final Translator trans = Application.getTranslator();
37
38         private final TableRowSorter<TableModel> sorter;
39         private final List<ComponentPreset> presets;
40         private final AbstractTableModel tableModel;
41         private final XTableColumnModel tableColumnModel;
42         private final ComponentPresetTableColumn[] columns;
43
44         public ComponentPresetTable(List<ComponentPreset> presets, List<TypedKey<?>> visibleColumnKeys) {
45                 super();
46                 this.presets = presets;
47                 this.columns = new ComponentPresetTableColumn[ComponentPreset.orderedKeyList.size()+1];
48
49                 tableColumnModel = new XTableColumnModel();
50
51                 /*
52                  * Set up the Column Table model
53                  */
54                 columns[0] = new ComponentPresetTableColumn.Favorite(0);
55                 tableColumnModel.addColumn(columns[0]);
56
57                 List<TableColumn> hiddenColumns = new ArrayList<TableColumn>();
58                 {
59                         int index = 1;
60                         for (final TypedKey<?> key: ComponentPreset.orderedKeyList ) {
61                                 if ( key.getType() == Double.class && key.getUnitGroup() != null ) {
62                                         columns[index] = new ComponentPresetTableColumn.DoubleWithUnit((TypedKey<Double>)key,index);
63                                 } else {
64                                         columns[index] = new ComponentPresetTableColumn.Parameter(key,index);
65                                 }
66                                 tableColumnModel.addColumn(columns[index]);
67                                 if ( visibleColumnKeys.indexOf(key) < 0 ) {
68                                         hiddenColumns.add(columns[index]);
69                                 }
70                                 index ++;
71                         }
72                 }
73
74
75                 tableModel = new AbstractTableModel() {
76                         final ComponentPresetTableColumn[] myColumns = columns;
77                         @Override
78                         public int getRowCount() {
79                                 return ComponentPresetTable.this.presets.size();
80                         }
81
82                         @Override
83                         public int getColumnCount() {
84                                 return myColumns.length;
85                         }
86
87                         @Override
88                         public Object getValueAt(int rowIndex, int columnIndex) {
89                                 return myColumns[columnIndex].getValueFromPreset(ComponentPresetTable.this.presets.get(rowIndex));
90                         }
91
92                         @Override
93                         public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
94                                 // Only support favorite
95                                 if ( columnIndex != 0 ) {
96                                         return;
97                                 }
98                                 ComponentPreset preset = ComponentPresetTable.this.presets.get(rowIndex);
99                                 Application.getComponentPresetDao().setFavorite(preset, (Boolean) aValue);
100                         }
101
102                         @Override
103                         public boolean isCellEditable(int rowIndex, int columnIndex) {
104                                 return columnIndex == 0;
105                         }
106
107                         @Override
108                         public Class<?> getColumnClass(int columnIndex) {
109                                 return columnIndex == 0 ? Boolean.class : Object.class;
110                         }
111
112                 };
113
114                 this.setAutoCreateColumnsFromModel(false);
115                 this.setColumnModel( tableColumnModel );
116                 this.setModel(tableModel);
117                 this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
118
119                 for ( TableColumn hiddenColumn : hiddenColumns ) {
120                         tableColumnModel.setColumnVisible(hiddenColumn, false);
121                 }
122
123                 sorter = new TableRowSorter<TableModel>(tableModel);
124                 this.setRowSorter(sorter);
125
126                 JTableHeader header = this.getTableHeader();
127                 
128                 header.setReorderingAllowed(true);
129
130                 header.addMouseListener( new MouseAdapter() {
131
132                         @Override
133                         public void mousePressed(MouseEvent e) {
134                                 if ( e.isPopupTrigger() ) {
135                                         doPopup(e);
136                                 }
137                         }
138                         @Override
139                         public void mouseReleased(MouseEvent e) {
140                                 if ( e.isPopupTrigger() ) {
141                                         doPopup(e);
142                                 }
143                         }
144                 });
145         }
146
147         public void setRowFilter( RowFilter<? super TableModel ,? super Integer> filter ) {
148                 sorter.setRowFilter( filter );
149         }
150
151         private void doPopup(MouseEvent evt ) {
152                 
153                 // Figure out what column header was clicked on.
154                 int colIndex = tableColumnModel.getColumnIndexAtX( evt.getX() );
155                 ComponentPresetTableColumn colClicked = null;
156                 if ( colIndex >=0 ) {
157                         colClicked = (ComponentPresetTableColumn) tableColumnModel.getColumn(colIndex);
158                 }
159                 
160                 JPopupMenu columnMenu = new ColumnPopupMenu(colClicked, colIndex);
161                 columnMenu.show(evt.getComponent(),evt.getX(),evt.getY());
162         }
163
164         private class ColumnPopupMenu extends JPopupMenu {
165
166                 ColumnPopupMenu(ComponentPresetTableColumn colClicked, int colClickedIndex) {
167                         if ( colClickedIndex >= 0 ) {
168                                 JCheckBoxMenuItem item = new SortAscColumnMenuItem(colClickedIndex);
169                                 this.add(item);
170                                 item = new SortDescColumnMenuItem(colClickedIndex);
171                                 this.add(item);
172                                 this.addSeparator();
173                                 if ( colClicked instanceof ComponentPresetTableColumn.DoubleWithUnit ) {
174                                         this.add( new UnitSelectorMenuItem( (ComponentPresetTableColumn.DoubleWithUnit) colClicked ));
175                                         this.addSeparator();
176                                 }
177                         }
178                         for( TableColumn c: columns ) {
179                                 JCheckBoxMenuItem item = new ToggleColumnMenuItem(c);
180                                 this.add(item);
181                         }
182                 }
183
184
185                 private class SortAscColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
186                         private int columnClicked;
187                         SortAscColumnMenuItem(int columnClicked) {
188                                 super( trans.get("ComponentPresetChooserDialog.menu.sortAsc") );
189                                 this.addItemListener(this);
190                                 this.columnClicked = columnClicked;
191                         }
192                         @Override
193                         public void itemStateChanged(ItemEvent e) {
194                                 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.ASCENDING)));
195                         }
196                 }
197                 
198                 private class SortDescColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
199                         private int columnClicked;
200                         SortDescColumnMenuItem(int columnClicked) {
201                                 super( trans.get("ComponentPresetChooserDialog.menu.sortDesc") );
202                                 this.addItemListener(this);
203                                 this.columnClicked = columnClicked;
204                         }
205                         @Override
206                         public void itemStateChanged(ItemEvent e) {
207                                 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.DESCENDING)));
208                         }
209                 }
210                 
211                 private class ToggleColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
212                         TableColumn col;
213                         ToggleColumnMenuItem( TableColumn col ) {
214                                 super( String.valueOf(col.getHeaderValue()), tableColumnModel.isColumnVisible(col));
215                                 this.addItemListener(this);
216                                 this.col = col;
217                         }
218                         @Override
219                         public void itemStateChanged(ItemEvent e) {
220                                 tableColumnModel.setColumnVisible(col, !tableColumnModel.isColumnVisible(col));
221                         }
222                 }
223                 
224                 private class UnitSelectorMenuItem extends JMenu implements ItemListener {
225                         ComponentPresetTableColumn.DoubleWithUnit col;
226                         UnitSelectorMenuItem( ComponentPresetTableColumn.DoubleWithUnit col ) {
227                                 super(trans.get("ComponentPresetChooserDialog.menu.units"));
228                                 this.col = col;
229                                 UnitGroup group = col.unitGroup;
230                                 Unit selectedUnit = col.selectedUnit;
231                                 for( Unit u : group.getUnits() ) {
232                                         JCheckBoxMenuItem item = new JCheckBoxMenuItem( u.toString() );
233                                         if ( u == selectedUnit ) {
234                                                 item.setSelected(true);
235                                         }
236                                         item.addItemListener(this);
237                                         this.add(item);
238                                 }
239                                 
240                         }
241                         @Override
242                         public void itemStateChanged(ItemEvent e) {
243                                 JCheckBoxMenuItem item = (JCheckBoxMenuItem) e.getItem();
244                                 String val = item.getText();
245                                 col.selectedUnit = col.unitGroup.findApproximate(val);
246                                 ComponentPresetTable.this.tableModel.fireTableDataChanged();
247                                 return;
248                         }
249
250                 }
251                 
252         }
253 }