001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.tagging; 003 004import java.awt.Component; 005 006import javax.swing.AbstractCellEditor; 007import javax.swing.BorderFactory; 008import javax.swing.JTable; 009import javax.swing.table.TableCellEditor; 010 011import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField; 012import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList; 013import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager; 014 015/** 016 * This is the table cell editor for the tag editor dialog. 017 * 018 */ 019public class TagCellEditor extends AbstractCellEditor implements TableCellEditor { 020 021 protected AutoCompletingTextField editor; 022 protected transient TagModel currentTag; 023 024 /** the cache of auto completion items derived from the current JOSM data set */ 025 protected transient AutoCompletionManager autocomplete; 026 027 /** user input is matched against this list of auto completion items */ 028 protected AutoCompletionList autoCompletionList; 029 030 /** 031 * constructor 032 * @param maxCharacters maximum number of characters allowed, 0 for unlimited 033 */ 034 public TagCellEditor(final int maxCharacters) { 035 editor = new AutoCompletingTextField(0, false); 036 if (maxCharacters > 0) { 037 editor.setMaxChars(maxCharacters); 038 } 039 editor.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); 040 } 041 042 /** 043 * initializes the auto completion list when the table cell editor starts 044 * to edit the key of a tag. In this case the auto completion list is 045 * initialized with the set of standard key values and the set of current key 046 * values from the current JOSM data set. Keys already present in the 047 * current tag model are removed from the auto completion list. 048 * 049 * @param model the tag editor model 050 * @param currentTag the current tag 051 */ 052 protected void initAutoCompletionListForKeys(TagEditorModel model, TagModel currentTag) { 053 054 if (autoCompletionList == null) 055 return; 056 autoCompletionList.clear(); 057 058 // add the list of keys in the current data set 059 // 060 autocomplete.populateWithKeys(autoCompletionList); 061 062 // remove the keys already present in the current tag model 063 // 064 for (String key : model.getKeys()) { 065 if (!key.equals(currentTag.getName())) { 066 autoCompletionList.remove(key); 067 } 068 } 069 autoCompletionList.fireTableDataChanged(); 070 } 071 072 /** 073 * initializes the auto completion list when the cell editor starts to edit 074 * a tag value. In this case the auto completion list is initialized with the 075 * set of standard values for a given key and the set of values present in the 076 * current data set for the given key. 077 * 078 * @param forKey the key 079 */ 080 protected void initAutoCompletionListForValues(String forKey) { 081 if (autoCompletionList == null) { 082 return; 083 } 084 autoCompletionList.clear(); 085 autocomplete.populateWithTagValues(autoCompletionList, forKey); 086 } 087 088 /** 089 * replies the table cell editor 090 */ 091 @Override 092 public Component getTableCellEditorComponent(JTable table, 093 Object value, boolean isSelected, int row, int column) { 094 currentTag = (TagModel) value; 095 096 // no autocompletion for initial editor#setText() 097 if (autoCompletionList != null) { 098 autoCompletionList.clear(); 099 } 100 if (column == 0) { 101 editor.setText(currentTag.getName()); 102 TagEditorModel model = (TagEditorModel) table.getModel(); 103 initAutoCompletionListForKeys(model, currentTag); 104 return editor; 105 } else if (column == 1) { 106 107 if (currentTag.getValueCount() > 1) { 108 editor.setText(""); 109 } else { 110 editor.setText(currentTag.getValue()); 111 } 112 initAutoCompletionListForValues(currentTag.getName()); 113 return editor; 114 } else { 115 return null; 116 } 117 } 118 119 @Override 120 public Object getCellEditorValue() { 121 return editor.getText(); 122 } 123 124 /** 125 * replies the {@link AutoCompletionList} this table cell editor synchronizes with 126 * 127 * @return the auto completion list 128 */ 129 public AutoCompletionList getAutoCompletionList() { 130 return autoCompletionList; 131 } 132 133 /** 134 * sets the {@link AutoCompletionList} this table cell editor synchronizes with 135 * @param autoCompletionList the auto completion list 136 */ 137 public void setAutoCompletionList(AutoCompletionList autoCompletionList) { 138 this.autoCompletionList = autoCompletionList; 139 editor.setAutoCompletionList(autoCompletionList); 140 } 141 142 /** 143 * Sets the manager that helps with auto completion 144 * @param autocomplete The {@link AutoCompletionManager} 145 */ 146 public void setAutoCompletionManager(AutoCompletionManager autocomplete) { 147 this.autocomplete = autocomplete; 148 } 149 150 /** 151 * Selects an item from the auto completion list and fills this cell with the value 152 * @param item The text that was selected 153 */ 154 public void autoCompletionItemSelected(String item) { 155 editor.setText(item); 156 editor.selectAll(); 157 editor.requestFocus(); 158 } 159 160 /** 161 * Gets the editor for this cell 162 * @return The editor text field 163 */ 164 public AutoCompletingTextField getEditor() { 165 return editor; 166 } 167}