1 package net.sf.openrocket.gui.dialogs.preset;
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.Comparator;
10 import java.util.List;
13 import javax.swing.JCheckBoxMenuItem;
14 import javax.swing.JMenu;
15 import javax.swing.JPopupMenu;
16 import javax.swing.JTable;
17 import javax.swing.ListSelectionModel;
18 import javax.swing.RowFilter;
19 import javax.swing.RowSorter.SortKey;
20 import javax.swing.SortOrder;
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;
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 import net.sf.openrocket.unit.Value;
34 import net.sf.openrocket.util.AlphanumComparator;
36 public class ComponentPresetTable extends JTable {
38 private static final Translator trans = Application.getTranslator();
40 private final TableRowSorter<TableModel> sorter;
41 private List<ComponentPreset> presets;
42 private final ComponentPreset.Type presetType;
43 private Set<String> favorites;
44 private final AbstractTableModel tableModel;
45 private final XTableColumnModel tableColumnModel;
46 private final ComponentPresetTableColumn[] columns;
48 public ComponentPresetTable(final ComponentPreset.Type presetType, List<ComponentPreset> presets, List<TypedKey<?>> visibleColumnKeys) {
50 this.presets = presets;
51 this.presetType = presetType;
52 this.favorites = Application.getPreferences().getComponentFavorites(presetType);
53 this.columns = new ComponentPresetTableColumn[ComponentPreset.ORDERED_KEY_LIST.size()+1];
56 tableModel = new AbstractTableModel() {
57 final ComponentPresetTableColumn[] myColumns = columns;
59 public int getRowCount() {
60 return ComponentPresetTable.this.presets.size();
64 public int getColumnCount() {
65 return myColumns.length;
69 public Object getValueAt(int rowIndex, int columnIndex) {
70 return myColumns[columnIndex].getValueFromPreset(favorites,ComponentPresetTable.this.presets.get(rowIndex));
74 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
75 // Only support favorite
76 if ( columnIndex != 0 ) {
79 ComponentPreset preset = ComponentPresetTable.this.presets.get(rowIndex);
80 Application.getComponentPresetDao().setFavorite(preset, presetType, (Boolean) aValue);
81 ComponentPresetTable.this.updateFavorites();
85 public boolean isCellEditable(int rowIndex, int columnIndex) {
86 return columnIndex == 0;
90 public Class<?> getColumnClass(int columnIndex) {
91 return columnIndex == 0 ? Boolean.class : Object.class;
97 sorter = new TableRowSorter<TableModel>(tableModel);
99 tableColumnModel = new XTableColumnModel();
102 * Set up the Column Table model, and customize the sorting.
104 columns[0] = new ComponentPresetTableColumn.Favorite(0);
105 tableColumnModel.addColumn(columns[0]);
107 List<TableColumn> hiddenColumns = new ArrayList<TableColumn>();
110 for (final TypedKey<?> key: ComponentPreset.ORDERED_KEY_LIST ) {
111 if ( key.getType() == Double.class && key.getUnitGroup() != null ) {
112 columns[index] = new ComponentPresetTableColumn.DoubleWithUnit((TypedKey<Double>)key,index);
114 columns[index] = new ComponentPresetTableColumn.Parameter(key,index);
116 tableColumnModel.addColumn(columns[index]);
117 if ( key == ComponentPreset.MANUFACTURER || key == ComponentPreset.PARTNO ) {
118 sorter.setComparator(index, new AlphanumComparator());
119 } else if ( key.getType() == Double.class ) {
120 sorter.setComparator(index, new Comparator<Value>() {
123 public int compare(Value o1, Value o2) {
124 return Double.compare(o1.getValue(), o2.getValue());
129 if ( visibleColumnKeys.indexOf(key) < 0 ) {
130 hiddenColumns.add(columns[index]);
136 this.setAutoCreateColumnsFromModel(false);
137 this.setColumnModel( tableColumnModel );
138 this.setModel(tableModel);
139 this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
140 this.setRowSorter(sorter);
142 for ( TableColumn hiddenColumn : hiddenColumns ) {
143 tableColumnModel.setColumnVisible(hiddenColumn, false);
146 JTableHeader header = this.getTableHeader();
148 header.setReorderingAllowed(true);
150 header.addMouseListener( new MouseAdapter() {
153 public void mousePressed(MouseEvent e) {
154 if ( e.isPopupTrigger() ) {
159 public void mouseReleased(MouseEvent e) {
160 if ( e.isPopupTrigger() ) {
167 public void setRowFilter( RowFilter<? super TableModel ,? super Integer> filter ) {
168 sorter.setRowFilter( filter );
171 public void updateData( List<ComponentPreset> presets ) {
172 this.presets = presets;
173 this.favorites = Application.getPreferences().getComponentFavorites(presetType);
174 this.tableModel.fireTableDataChanged();
177 public void updateFavorites() {
178 this.favorites = Application.getPreferences().getComponentFavorites(presetType);
179 this.tableModel.fireTableDataChanged();
182 private void doPopup(MouseEvent evt ) {
184 // Figure out what column header was clicked on.
185 int colIndex = tableColumnModel.getColumnIndexAtX( evt.getX() );
186 ComponentPresetTableColumn colClicked = null;
187 if ( colIndex >=0 ) {
188 colClicked = (ComponentPresetTableColumn) tableColumnModel.getColumn(colIndex);
191 JPopupMenu columnMenu = new ColumnPopupMenu(colClicked, colIndex);
192 columnMenu.show(evt.getComponent(),evt.getX(),evt.getY());
195 private class ColumnPopupMenu extends JPopupMenu {
197 ColumnPopupMenu(ComponentPresetTableColumn colClicked, int colClickedIndex) {
198 if ( colClickedIndex >= 0 ) {
199 JCheckBoxMenuItem item = new SortAscColumnMenuItem(colClickedIndex);
201 item = new SortDescColumnMenuItem(colClickedIndex);
204 if ( colClicked instanceof ComponentPresetTableColumn.DoubleWithUnit ) {
205 this.add( new UnitSelectorMenuItem( (ComponentPresetTableColumn.DoubleWithUnit) colClicked ));
209 for( TableColumn c: columns ) {
210 JCheckBoxMenuItem item = new ToggleColumnMenuItem(c);
216 private class SortAscColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
217 private int columnClicked;
218 SortAscColumnMenuItem(int columnClicked) {
219 super( trans.get("ComponentPresetChooserDialog.menu.sortAsc") );
220 this.addItemListener(this);
221 this.columnClicked = columnClicked;
224 public void itemStateChanged(ItemEvent e) {
225 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.ASCENDING)));
229 private class SortDescColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
230 private int columnClicked;
231 SortDescColumnMenuItem(int columnClicked) {
232 super( trans.get("ComponentPresetChooserDialog.menu.sortDesc") );
233 this.addItemListener(this);
234 this.columnClicked = columnClicked;
237 public void itemStateChanged(ItemEvent e) {
238 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.DESCENDING)));
242 private class ToggleColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
244 ToggleColumnMenuItem( TableColumn col ) {
245 super( String.valueOf(col.getHeaderValue()), tableColumnModel.isColumnVisible(col));
246 this.addItemListener(this);
250 public void itemStateChanged(ItemEvent e) {
251 tableColumnModel.setColumnVisible(col, !tableColumnModel.isColumnVisible(col));
255 private class UnitSelectorMenuItem extends JMenu implements ItemListener {
256 ComponentPresetTableColumn.DoubleWithUnit col;
257 UnitSelectorMenuItem( ComponentPresetTableColumn.DoubleWithUnit col ) {
258 super(trans.get("ComponentPresetChooserDialog.menu.units"));
260 UnitGroup group = col.unitGroup;
261 Unit selectedUnit = col.selectedUnit;
262 for( Unit u : group.getUnits() ) {
263 JCheckBoxMenuItem item = new JCheckBoxMenuItem( u.toString() );
264 if ( u == selectedUnit ) {
265 item.setSelected(true);
267 item.addItemListener(this);
273 public void itemStateChanged(ItemEvent e) {
274 JCheckBoxMenuItem item = (JCheckBoxMenuItem) e.getItem();
275 String val = item.getText();
276 col.selectedUnit = col.unitGroup.findApproximate(val);
277 ComponentPresetTable.this.tableModel.fireTableDataChanged();