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;
12 import javax.swing.JCheckBoxMenuItem;
13 import javax.swing.JMenu;
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.table.AbstractTableModel;
21 import javax.swing.table.JTableHeader;
22 import javax.swing.table.TableColumn;
23 import javax.swing.table.TableModel;
24 import javax.swing.table.TableRowSorter;
26 import net.sf.openrocket.l10n.Translator;
27 import net.sf.openrocket.preset.ComponentPreset;
28 import net.sf.openrocket.preset.TypedKey;
29 import net.sf.openrocket.startup.Application;
30 import net.sf.openrocket.unit.Unit;
31 import net.sf.openrocket.unit.UnitGroup;
32 import net.sf.openrocket.unit.Value;
33 import net.sf.openrocket.util.AlphanumComparator;
35 public class ComponentPresetTable extends JTable {
37 private static final Translator trans = Application.getTranslator();
39 private final TableRowSorter<TableModel> sorter;
40 private List<ComponentPreset> presets;
41 private final AbstractTableModel tableModel;
42 private final XTableColumnModel tableColumnModel;
43 private final ComponentPresetTableColumn[] columns;
45 public ComponentPresetTable(List<ComponentPreset> presets, List<TypedKey<?>> visibleColumnKeys) {
47 this.presets = presets;
48 this.columns = new ComponentPresetTableColumn[ComponentPreset.ORDERED_KEY_LIST.size()+1];
51 tableModel = new AbstractTableModel() {
52 final ComponentPresetTableColumn[] myColumns = columns;
54 public int getRowCount() {
55 return ComponentPresetTable.this.presets.size();
59 public int getColumnCount() {
60 return myColumns.length;
64 public Object getValueAt(int rowIndex, int columnIndex) {
65 return myColumns[columnIndex].getValueFromPreset(ComponentPresetTable.this.presets.get(rowIndex));
69 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
70 // Only support favorite
71 if ( columnIndex != 0 ) {
74 ComponentPreset preset = ComponentPresetTable.this.presets.get(rowIndex);
75 Application.getComponentPresetDao().setFavorite(preset, (Boolean) aValue);
79 public boolean isCellEditable(int rowIndex, int columnIndex) {
80 return columnIndex == 0;
84 public Class<?> getColumnClass(int columnIndex) {
85 return columnIndex == 0 ? Boolean.class : Object.class;
91 sorter = new TableRowSorter<TableModel>(tableModel);
93 tableColumnModel = new XTableColumnModel();
96 * Set up the Column Table model, and customize the sorting.
98 columns[0] = new ComponentPresetTableColumn.Favorite(0);
99 tableColumnModel.addColumn(columns[0]);
101 List<TableColumn> hiddenColumns = new ArrayList<TableColumn>();
104 for (final TypedKey<?> key: ComponentPreset.ORDERED_KEY_LIST ) {
105 if ( key.getType() == Double.class && key.getUnitGroup() != null ) {
106 columns[index] = new ComponentPresetTableColumn.DoubleWithUnit((TypedKey<Double>)key,index);
108 columns[index] = new ComponentPresetTableColumn.Parameter(key,index);
110 tableColumnModel.addColumn(columns[index]);
111 if ( key == ComponentPreset.MANUFACTURER || key == ComponentPreset.PARTNO ) {
112 sorter.setComparator(index, new AlphanumComparator());
113 } else if ( key.getType() == Double.class ) {
114 sorter.setComparator(index, new Comparator<Value>() {
117 public int compare(Value o1, Value o2) {
118 return Double.compare(o1.getValue(), o2.getValue());
123 if ( visibleColumnKeys.indexOf(key) < 0 ) {
124 hiddenColumns.add(columns[index]);
130 this.setAutoCreateColumnsFromModel(false);
131 this.setColumnModel( tableColumnModel );
132 this.setModel(tableModel);
133 this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
134 this.setRowSorter(sorter);
136 for ( TableColumn hiddenColumn : hiddenColumns ) {
137 tableColumnModel.setColumnVisible(hiddenColumn, false);
140 JTableHeader header = this.getTableHeader();
142 header.setReorderingAllowed(true);
144 header.addMouseListener( new MouseAdapter() {
147 public void mousePressed(MouseEvent e) {
148 if ( e.isPopupTrigger() ) {
153 public void mouseReleased(MouseEvent e) {
154 if ( e.isPopupTrigger() ) {
161 public void setRowFilter( RowFilter<? super TableModel ,? super Integer> filter ) {
162 sorter.setRowFilter( filter );
165 public void updateData( List<ComponentPreset> presets ) {
166 this.presets = presets;
167 this.tableModel.fireTableDataChanged();
170 private void doPopup(MouseEvent evt ) {
172 // Figure out what column header was clicked on.
173 int colIndex = tableColumnModel.getColumnIndexAtX( evt.getX() );
174 ComponentPresetTableColumn colClicked = null;
175 if ( colIndex >=0 ) {
176 colClicked = (ComponentPresetTableColumn) tableColumnModel.getColumn(colIndex);
179 JPopupMenu columnMenu = new ColumnPopupMenu(colClicked, colIndex);
180 columnMenu.show(evt.getComponent(),evt.getX(),evt.getY());
183 private class ColumnPopupMenu extends JPopupMenu {
185 ColumnPopupMenu(ComponentPresetTableColumn colClicked, int colClickedIndex) {
186 if ( colClickedIndex >= 0 ) {
187 JCheckBoxMenuItem item = new SortAscColumnMenuItem(colClickedIndex);
189 item = new SortDescColumnMenuItem(colClickedIndex);
192 if ( colClicked instanceof ComponentPresetTableColumn.DoubleWithUnit ) {
193 this.add( new UnitSelectorMenuItem( (ComponentPresetTableColumn.DoubleWithUnit) colClicked ));
197 for( TableColumn c: columns ) {
198 JCheckBoxMenuItem item = new ToggleColumnMenuItem(c);
204 private class SortAscColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
205 private int columnClicked;
206 SortAscColumnMenuItem(int columnClicked) {
207 super( trans.get("ComponentPresetChooserDialog.menu.sortAsc") );
208 this.addItemListener(this);
209 this.columnClicked = columnClicked;
212 public void itemStateChanged(ItemEvent e) {
213 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.ASCENDING)));
217 private class SortDescColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
218 private int columnClicked;
219 SortDescColumnMenuItem(int columnClicked) {
220 super( trans.get("ComponentPresetChooserDialog.menu.sortDesc") );
221 this.addItemListener(this);
222 this.columnClicked = columnClicked;
225 public void itemStateChanged(ItemEvent e) {
226 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.DESCENDING)));
230 private class ToggleColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
232 ToggleColumnMenuItem( TableColumn col ) {
233 super( String.valueOf(col.getHeaderValue()), tableColumnModel.isColumnVisible(col));
234 this.addItemListener(this);
238 public void itemStateChanged(ItemEvent e) {
239 tableColumnModel.setColumnVisible(col, !tableColumnModel.isColumnVisible(col));
243 private class UnitSelectorMenuItem extends JMenu implements ItemListener {
244 ComponentPresetTableColumn.DoubleWithUnit col;
245 UnitSelectorMenuItem( ComponentPresetTableColumn.DoubleWithUnit col ) {
246 super(trans.get("ComponentPresetChooserDialog.menu.units"));
248 UnitGroup group = col.unitGroup;
249 Unit selectedUnit = col.selectedUnit;
250 for( Unit u : group.getUnits() ) {
251 JCheckBoxMenuItem item = new JCheckBoxMenuItem( u.toString() );
252 if ( u == selectedUnit ) {
253 item.setSelected(true);
255 item.addItemListener(this);
261 public void itemStateChanged(ItemEvent e) {
262 JCheckBoxMenuItem item = (JCheckBoxMenuItem) e.getItem();
263 String val = item.getText();
264 col.selectedUnit = col.unitGroup.findApproximate(val);
265 ComponentPresetTable.this.tableModel.fireTableDataChanged();