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() == 0) { 108 editor.setText(""); 109 } else if (currentTag.getValueCount() == 1) { 110 editor.setText(currentTag.getValues().get(0)); 111 } else { 112 editor.setText(""); 113 } 114 initAutoCompletionListForValues(currentTag.getName()); 115 return editor; 116 } else { 117 return null; 118 } 119 } 120 121 @Override 122 public Object getCellEditorValue() { 123 return editor.getText(); 124 } 125 126 /** 127 * replies the {@link AutoCompletionList} this table cell editor synchronizes with 128 * 129 * @return the auto completion list 130 */ 131 public AutoCompletionList getAutoCompletionList() { 132 return autoCompletionList; 133 } 134 135 /** 136 * sets the {@link AutoCompletionList} this table cell editor synchronizes with 137 * @param autoCompletionList the auto completion list 138 */ 139 public void setAutoCompletionList(AutoCompletionList autoCompletionList) { 140 this.autoCompletionList = autoCompletionList; 141 editor.setAutoCompletionList(autoCompletionList); 142 } 143 144 public void setAutoCompletionManager(AutoCompletionManager autocomplete) { 145 this.autocomplete = autocomplete; 146 } 147 148 public void autoCompletionItemSelected(String item) { 149 editor.setText(item); 150 editor.selectAll(); 151 editor.requestFocus(); 152 } 153 154 public AutoCompletingTextField getEditor() { 155 return editor; 156 } 157}