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.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;
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;
34 public class ComponentPresetTable extends JTable {
36 private static final Translator trans = Application.getTranslator();
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;
44 public ComponentPresetTable(List<ComponentPreset> presets, List<TypedKey<?>> visibleColumnKeys) {
46 this.presets = presets;
47 this.columns = new ComponentPresetTableColumn[ComponentPreset.orderedKeyList.size()+1];
49 tableColumnModel = new XTableColumnModel();
52 * Set up the Column Table model
54 columns[0] = new ComponentPresetTableColumn.Favorite(0);
55 tableColumnModel.addColumn(columns[0]);
57 List<TableColumn> hiddenColumns = new ArrayList<TableColumn>();
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);
64 columns[index] = new ComponentPresetTableColumn.Parameter(key,index);
66 tableColumnModel.addColumn(columns[index]);
67 if ( visibleColumnKeys.indexOf(key) < 0 ) {
68 hiddenColumns.add(columns[index]);
75 tableModel = new AbstractTableModel() {
76 final ComponentPresetTableColumn[] myColumns = columns;
78 public int getRowCount() {
79 return ComponentPresetTable.this.presets.size();
83 public int getColumnCount() {
84 return myColumns.length;
88 public Object getValueAt(int rowIndex, int columnIndex) {
89 return myColumns[columnIndex].getValueFromPreset(ComponentPresetTable.this.presets.get(rowIndex));
93 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
94 // Only support favorite
95 if ( columnIndex != 0 ) {
98 ComponentPreset preset = ComponentPresetTable.this.presets.get(rowIndex);
99 Application.getComponentPresetDao().setFavorite(preset, (Boolean) aValue);
103 public boolean isCellEditable(int rowIndex, int columnIndex) {
104 return columnIndex == 0;
108 public Class<?> getColumnClass(int columnIndex) {
109 return columnIndex == 0 ? Boolean.class : Object.class;
114 this.setAutoCreateColumnsFromModel(false);
115 this.setColumnModel( tableColumnModel );
116 this.setModel(tableModel);
117 this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
119 for ( TableColumn hiddenColumn : hiddenColumns ) {
120 tableColumnModel.setColumnVisible(hiddenColumn, false);
123 sorter = new TableRowSorter<TableModel>(tableModel);
124 this.setRowSorter(sorter);
126 JTableHeader header = this.getTableHeader();
128 header.setReorderingAllowed(true);
130 header.addMouseListener( new MouseAdapter() {
133 public void mousePressed(MouseEvent e) {
134 if ( e.isPopupTrigger() ) {
139 public void mouseReleased(MouseEvent e) {
140 if ( e.isPopupTrigger() ) {
147 public void setRowFilter( RowFilter<? super TableModel ,? super Integer> filter ) {
148 sorter.setRowFilter( filter );
151 private void doPopup(MouseEvent evt ) {
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);
160 JPopupMenu columnMenu = new ColumnPopupMenu(colClicked, colIndex);
161 columnMenu.show(evt.getComponent(),evt.getX(),evt.getY());
164 private class ColumnPopupMenu extends JPopupMenu {
166 ColumnPopupMenu(ComponentPresetTableColumn colClicked, int colClickedIndex) {
167 if ( colClickedIndex >= 0 ) {
168 JCheckBoxMenuItem item = new SortAscColumnMenuItem(colClickedIndex);
170 item = new SortDescColumnMenuItem(colClickedIndex);
173 if ( colClicked instanceof ComponentPresetTableColumn.DoubleWithUnit ) {
174 this.add( new UnitSelectorMenuItem( (ComponentPresetTableColumn.DoubleWithUnit) colClicked ));
178 for( TableColumn c: columns ) {
179 JCheckBoxMenuItem item = new ToggleColumnMenuItem(c);
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;
193 public void itemStateChanged(ItemEvent e) {
194 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.ASCENDING)));
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;
206 public void itemStateChanged(ItemEvent e) {
207 sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.DESCENDING)));
211 private class ToggleColumnMenuItem extends JCheckBoxMenuItem implements ItemListener {
213 ToggleColumnMenuItem( TableColumn col ) {
214 super( String.valueOf(col.getHeaderValue()), tableColumnModel.isColumnVisible(col));
215 this.addItemListener(this);
219 public void itemStateChanged(ItemEvent e) {
220 tableColumnModel.setColumnVisible(col, !tableColumnModel.isColumnVisible(col));
224 private class UnitSelectorMenuItem extends JMenu implements ItemListener {
225 ComponentPresetTableColumn.DoubleWithUnit col;
226 UnitSelectorMenuItem( ComponentPresetTableColumn.DoubleWithUnit col ) {
227 super(trans.get("ComponentPresetChooserDialog.menu.units"));
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);
236 item.addItemListener(this);
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();