001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.gui.conflict.tags;
003
004 import java.awt.event.ActionEvent;
005 import java.awt.event.KeyEvent;
006
007 import javax.swing.AbstractAction;
008 import javax.swing.JComponent;
009 import javax.swing.JTable;
010 import javax.swing.KeyStroke;
011 import javax.swing.ListSelectionModel;
012
013 import org.openstreetmap.josm.gui.widgets.JosmComboBox;
014
015 public class RelationMemberConflictResolverTable extends JTable implements MultiValueCellEditor.NavigationListener {
016
017 private SelectNextColumnCellAction selectNextColumnCellAction;
018 private SelectPreviousColumnCellAction selectPreviousColumnCellAction;
019
020 public RelationMemberConflictResolverTable(RelationMemberConflictResolverModel model) {
021 super(model, new RelationMemberConflictResolverColumnModel());
022 build();
023 }
024
025 protected void build() {
026 setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
027 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
028 putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
029
030 // make ENTER behave like TAB
031 //
032 getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
033 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "selectNextColumnCell");
034
035 // install custom navigation actions
036 //
037 selectNextColumnCellAction = new SelectNextColumnCellAction();
038 selectPreviousColumnCellAction = new SelectPreviousColumnCellAction();
039 getActionMap().put("selectNextColumnCell", selectNextColumnCellAction);
040 getActionMap().put("selectPreviousColumnCell", selectPreviousColumnCellAction);
041
042 setRowHeight((int)new JosmComboBox().getPreferredSize().getHeight());
043 }
044
045 /**
046 * Action to be run when the user navigates to the next cell in the table, for instance by
047 * pressing TAB or ENTER. The action alters the standard navigation path from cell to cell: <ul>
048 * <li>it jumps over cells in the first column</li> <li>it automatically add a new empty row
049 * when the user leaves the last cell in the table</li> <ul>
050 *
051 *
052 */
053 class SelectNextColumnCellAction extends AbstractAction {
054 public void actionPerformed(ActionEvent e) {
055 run();
056 }
057
058 public void run() {
059 int col = getSelectedColumn();
060 int row = getSelectedRow();
061 if (getCellEditor() != null) {
062 getCellEditor().stopCellEditing();
063 }
064
065 if (col == 2 && row < getRowCount() - 1) {
066 row++;
067 } else if (row < getRowCount() - 1) {
068 col = 2;
069 row++;
070 }
071 changeSelection(row, col, false, false);
072 editCellAt(getSelectedRow(), getSelectedColumn());
073 getEditorComponent().requestFocusInWindow();
074 }
075 }
076
077 /**
078 * Action to be run when the user navigates to the previous cell in the table, for instance by
079 * pressing Shift-TAB
080 *
081 */
082 class SelectPreviousColumnCellAction extends AbstractAction {
083
084 public void actionPerformed(ActionEvent e) {
085 run();
086 }
087
088 public void run() {
089 int col = getSelectedColumn();
090 int row = getSelectedRow();
091 if (getCellEditor() != null) {
092 getCellEditor().stopCellEditing();
093 }
094
095 if (col <= 0 && row <= 0) {
096 // change nothing
097 } else if (row > 0) {
098 col = 2;
099 row--;
100 }
101 changeSelection(row, col, false, false);
102 editCellAt(getSelectedRow(), getSelectedColumn());
103 getEditorComponent().requestFocusInWindow();
104 }
105 }
106
107 public void gotoNextDecision() {
108 selectNextColumnCellAction.run();
109 }
110
111 public void gotoPreviousDecision() {
112 selectPreviousColumnCellAction.run();
113 }
114 }