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 TagConflictResolverTable extends JTable implements MultiValueCellEditor.NavigationListener {
016
017 private SelectNextColumnCellAction selectNextColumnCellAction;
018 private SelectPreviousColumnCellAction selectPreviousColumnCellAction;
019
020 public TagConflictResolverTable(TagConflictResolverModel model) {
021 super(model, new TagConflictResolverColumnModel());
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 ((MultiValueCellEditor)getColumnModel().getColumn(2).getCellEditor()).addNavigationListeners(this);
043
044 setRowHeight((int)new JosmComboBox().getPreferredSize().getHeight());
045 }
046
047 /**
048 * Action to be run when the user navigates to the next cell in the table, for instance by
049 * pressing TAB or ENTER. The action alters the standard navigation path from cell to cell: <ul>
050 * <li>it jumps over cells in the first column</li> <li>it automatically add a new empty row
051 * when the user leaves the last cell in the table</li> <ul>
052 *
053 *
054 */
055 class SelectNextColumnCellAction extends AbstractAction {
056 public void actionPerformed(ActionEvent e) {
057 run();
058 }
059
060 public void run() {
061 int col = getSelectedColumn();
062 int row = getSelectedRow();
063 if (getCellEditor() != null) {
064 getCellEditor().stopCellEditing();
065 }
066
067 if (col == 2 && row < getRowCount() - 1) {
068 row++;
069 } else if (row < getRowCount() - 1) {
070 col = 2;
071 row++;
072 }
073 changeSelection(row, col, false, false);
074 editCellAt(getSelectedRow(), getSelectedColumn());
075 getEditorComponent().requestFocusInWindow();
076 }
077 }
078
079 /**
080 * Action to be run when the user navigates to the previous cell in the table, for instance by
081 * pressing Shift-TAB
082 *
083 */
084 class SelectPreviousColumnCellAction extends AbstractAction {
085
086 public void actionPerformed(ActionEvent e) {
087 run();
088 }
089
090 public void run() {
091 int col = getSelectedColumn();
092 int row = getSelectedRow();
093 if (getCellEditor() != null) {
094 getCellEditor().stopCellEditing();
095 }
096
097 if (col <= 0 && row <= 0) {
098 // change nothing
099 } else if (row > 0) {
100 col = 2;
101 row--;
102 }
103 changeSelection(row, col, false, false);
104 editCellAt(getSelectedRow(), getSelectedColumn());
105 getEditorComponent().requestFocusInWindow();
106 }
107 }
108
109 public void gotoNextDecision() {
110 selectNextColumnCellAction.run();
111 }
112
113 public void gotoPreviousDecision() {
114 selectPreviousColumnCellAction.run();
115 }
116 }