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;
11 import javax.swing.JCheckBoxMenuItem;
12 import javax.swing.JMenu;
13 import javax.swing.JPopupMenu;
14 import javax.swing.JTable;
15 import javax.swing.ListSelectionModel;
16 import javax.swing.RowFilter;
17 import javax.swing.RowSorter.SortKey;
18 import javax.swing.SortOrder;
19 import javax.swing.table.AbstractTableModel;
20 import javax.swing.table.JTableHeader;
21 import javax.swing.table.TableColumn;
22 import javax.swing.table.TableModel;
23 import javax.swing.table.TableRowSorter;
25 import net.sf.openrocket.l10n.Translator;
26 import net.sf.openrocket.preset.ComponentPreset;
27 import net.sf.openrocket.preset.TypedKey;
28 import net.sf.openrocket.startup.Application;
29 import net.sf.openrocket.unit.Unit;
30 import net.sf.openrocket.unit.UnitGroup;
31 import net.sf.openrocket.util.AlphanumComparator;
33 public class ComponentPresetTable extends JTable {
35 private static final Translator trans = Application.getTranslator();
37 private final TableRowSorter<TableModel> sorter;
38 private List<ComponentPreset> presets;
39 private final AbstractTableModel tableModel;
40 private final XTableColumnModel tableColumnModel;
41 private final ComponentPresetTableColumn[] columns;
43 public ComponentPresetTable(List<ComponentPreset> presets, List<TypedKey<?>> visibleColumnKeys) {
45 this.presets = presets;
46 this.columns = new ComponentPresetTableColumn[ComponentPreset.orderedKeyList.size()+1];
49 tableModel = new AbstractTableModel() {
50 final ComponentPresetTableColumn[] myColumns = columns;
52 public int getRowCount() {
53 return ComponentPresetTable.this.presets.size();
57 public int getColumnCount() {
58 return myColumns.length;
62 public Object getValueAt(int rowIndex, int columnIndex) {
63 return myColumns[columnIndex].getValueFromPreset(ComponentPresetTable.this.presets.get(rowIndex));
67 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
68 // Only support favorite
69 if ( columnIndex != 0 ) {
72 ComponentPreset preset = ComponentPresetTable.this.presets.get(rowIndex);
73 Application.getComponentPresetDao().setFavorite(preset, (Boolean) aValue);
77 public boolean isCellEditable(int rowIndex, int columnIndex) {
78 return columnIndex == 0;
82 public Class<?> getColumnClass(int columnIndex) {
83 return columnIndex == 0 ? Boolean.class : Object.class;
89 sorter = new TableRowSorter<TableModel>(tableModel);
91 tableColumnModel = new XTableColumnModel();
94 * Set up the Column Table model, and customize the sorting.
96 columns[0] = new ComponentPresetTableColumn.Favorite(0);
97 tableColumnModel.addColumn(columns[0]);
99 List<TableColumn> hiddenColumns = new ArrayList<TableColumn>();
102 for (final TypedKey<?> key: ComponentPreset.orderedKeyList ) {
103 if ( key.getType() == Double.class && key.getUnitGroup() != null ) {
104 columns[index] = new ComponentPresetTableColumn.DoubleWithUnit((TypedKey<Double>)key,index);
106 columns[index] = new ComponentPresetTableColumn.Parameter(key,index);
108 tableColumnModel.addColumn(columns[index]);
109 if ( key == ComponentPreset.MANUFACTURER || key == ComponentPreset.PARTNO ) {
110 sorter.setComparator(index, new AlphanumComparator());
112 if ( visibleColumnKeys.indexOf(key) < 0 ) {
113 hiddenColumns.add(columns[index]);
119 this.setAutoCreateColumnsFromModel(false);
120 this.setColumnModel( tableColumnModel );
121 this.setModel(tableModel);
122 this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
123 this.setRowSorter(sorter);
125 for ( TableColumn hiddenColumn : hiddenColumns ) {
126 tableColumnModel.setColumnVisible(hiddenColumn, false);
129 JTableHeader header = this.getTableHeader();
131 header.setReorderingAllowed(true);
133 header.addMouseListener( new MouseAdapter() {
136 public void mousePressed(MouseEvent e) {
137 if ( e.isPopupTrigger() ) {
142 public void mouseReleased(MouseEvent e) {
143 if ( e.isPopupTrigger() ) {
150 public void setRowFilter( RowFilter<? super TableModel ,? super Integer> filter ) {
151 sorter.setRowFilter( filter );
154 public void updateData( List<ComponentPreset> presets ) {
155 this.presets = presets;
156 this.tableModel.fireTableDataChanged();
159 private void doPopup(MouseEvent evt ) {
161 // Figure out what column header was clicked on.
162 int colIndex = tableColumnModel.getColumnIndexAtX( evt.getX() );
163 ComponentPresetTableColumn colClicked = null;
164 if ( colIndex >=0 ) {
165 colClicked = (ComponentPresetTableColumn) tableColumnModel.getColumn(colIndex);
168 JPopupMenu columnMenu = new ColumnPopupMenu(colClicked, colIndex);
169 columnMenu.show(evt.getComponent(),evt.getX(),evt.getY());
172 private class ColumnPopupMenu extends JPopupMenu {
174 ColumnPopupMenu(ComponentPresetTableColumn colClicked, int colClickedIndex) {
175 if ( colClickedIndex >= 0 ) {
176 JCheckBoxMenuItem item = new SortAscColumnMenuItem(colClickedIndex);
178 item = new SortDescColumnMenuItem(colClickedIndex);
181 if ( colClicked instanceof ComponentPresetTableColumn.DoubleWithUnit ) {
182 this.add( new UnitSelectorMenuItem( (ComponentPresetTableColumn.DoubleWithUnit) colClicked ));
186 for( TableColumn c: columns ) {
187 JCheckBoxMenuItem item = new ToggleColumnMenuItem(c);
193 private class SortAscColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
194 private int columnClicked;
195 SortAscColumnMenuItem(int columnClicked) {
196 super( trans.get("ComponentPresetChooserDialog.menu.sortAsc") );
197 this.addItemListener(this);
198 this.columnClicked = columnClicked;
201 public void itemStateChanged(ItemEvent e) {
202 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.ASCENDING)));
206 private class SortDescColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
207 private int columnClicked;
208 SortDescColumnMenuItem(int columnClicked) {
209 super( trans.get("ComponentPresetChooserDialog.menu.sortDesc") );
210 this.addItemListener(this);
211 this.columnClicked = columnClicked;
214 public void itemStateChanged(ItemEvent e) {
215 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.DESCENDING)));
219 private class ToggleColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
221 ToggleColumnMenuItem( TableColumn col ) {
222 super( String.valueOf(col.getHeaderValue()), tableColumnModel.isColumnVisible(col));
223 this.addItemListener(this);
227 public void itemStateChanged(ItemEvent e) {
228 tableColumnModel.setColumnVisible(col, !tableColumnModel.isColumnVisible(col));
232 private class UnitSelectorMenuItem extends JMenu implements ItemListener {
233 ComponentPresetTableColumn.DoubleWithUnit col;
234 UnitSelectorMenuItem( ComponentPresetTableColumn.DoubleWithUnit col ) {
235 super(trans.get("ComponentPresetChooserDialog.menu.units"));
237 UnitGroup group = col.unitGroup;
238 Unit selectedUnit = col.selectedUnit;
239 for( Unit u : group.getUnits() ) {
240 JCheckBoxMenuItem item = new JCheckBoxMenuItem( u.toString() );
241 if ( u == selectedUnit ) {
242 item.setSelected(true);
244 item.addItemListener(this);
250 public void itemStateChanged(ItemEvent e) {
251 JCheckBoxMenuItem item = (JCheckBoxMenuItem) e.getItem();
252 String val = item.getText();
253 col.selectedUnit = col.unitGroup.findApproximate(val);
254 ComponentPresetTable.this.tableModel.fireTableDataChanged();