Changeset 15319 in osm for applications/editors/josm/plugins/tageditor
- Timestamp:
- 2009-05-30T13:00:04+02:00 (15 years ago)
- Location:
- applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/LaunchAction.java
r14322 r15319 27 27 @SuppressWarnings("serial") 28 28 public class LaunchAction extends JosmAction implements SelectionChangedListener { 29 29 30 30 protected void registerAsMenuItem() { 31 32 33 31 JMenuBar menu = Main.main.menu; 32 JMenu edit = null; 33 JMenuItem item = new JMenuItem(this); 34 34 35 36 37 38 39 40 41 35 for (int i = 0; i < menu.getMenuCount(); ++i) { 36 if (menu.getMenu(i) != null 37 && tr("Edit").equals(menu.getMenu(i).getText())) { 38 edit = menu.getMenu(i); 39 break; 40 } 41 } 42 42 43 44 45 46 47 48 49 50 43 if (edit != null) { 44 edit.insertSeparator(edit.getItemCount()); 45 JMenuItem mitem = edit.insert(this, edit.getItemCount()); 46 mitem.setAccelerator(KeyStroke.getKeyStroke('T')); 47 } else if (menu.getMenuCount() > 0) { 48 edit = menu.getMenu(0); 49 JMenuItem mitem = edit.insert(this, 0); 50 mitem.setAccelerator(KeyStroke.getKeyStroke('T')); 51 51 52 52 } 53 53 54 54 item.setVisible(true); 55 55 } 56 57 58 56 59 57 public LaunchAction() { 60 58 super( 61 tr("Edit tags"),62 null, //TODO: set "tag-editor" and add /images/tag-editor.png to distrib63 tr("Launches the tag editor dialog"),64 Shortcut.registerShortcut(65 "edit:launchtageditor",66 tr("Launches the tag editor dialog"),67 KeyEvent.VK_T,68 Shortcut.GROUP_EDIT),69 false // don't register, plugin will add the action to the menu59 tr("Edit tags"), 60 null, //TODO: set "tag-editor" and add /images/tag-editor.png to distrib 61 tr("Launches the tag editor dialog"), 62 Shortcut.registerShortcut( 63 "edit:launchtageditor", 64 tr("Launches the tag editor dialog"), 65 KeyEvent.VK_T, 66 Shortcut.GROUP_EDIT), 67 false // don't register, plugin will add the action to the menu 70 68 ); 71 72 69 70 73 71 // register as dataset selection listener 74 72 // 75 73 DataSet.selListeners.add(this); 76 74 77 75 // insert a menu item 78 76 // 79 77 registerAsMenuItem(); 80 78 81 79 // initially not enabled; becomes enabled when the selection becomes non-empty 82 80 // 83 81 setEnabled(false); 84 82 85 83 } 86 84 87 85 /** 88 * 86 * 89 87 * @return the top window of the JOSM GUI; can be null 90 88 */ 91 89 protected Window getTopWindow() { 92 if (Main.contentPane == null) {90 if (Main.contentPane == null) 93 91 return null; 94 }95 92 Component c = Main.contentPane; 96 93 while(c.getParent() != null) { 97 94 c = c.getParent(); 98 95 } 99 if (c instanceof Window) {96 if (c instanceof Window) 100 97 return (Window)c; 101 } else {98 else 102 99 return null; 103 }104 100 } 105 101 106 102 /** 107 * tries to center the tag editor dialog on the top window or, alternatively, 103 * tries to center the tag editor dialog on the top window or, alternatively, 108 104 * on the screen 109 105 * 110 * @param dialog the dialog to be placed on the screen 106 * @param dialog the dialog to be placed on the screen 111 107 */ 112 108 protected void placeDialogOnScreen(TagEditorDialog dialog) { 113 109 Window w = getTopWindow(); 114 if (w == null) {115 // don't center 110 if (w == null) 111 // don't center 116 112 return; 117 } 118 113 119 114 GraphicsConfiguration gc = w.getGraphicsConfiguration(); 120 115 Rectangle screenBounds = null; … … 135 130 136 131 dialog.setLocation(p); 137 132 138 133 } 139 134 140 135 /** 141 * launch the editor 136 * launch the editor 142 137 */ 143 138 protected void launchEditor() { 144 if (!isEnabled()) {139 if (!isEnabled()) 145 140 return; 146 }147 141 TagEditorDialog dialog = TagEditorDialog.getInstance(); 148 142 placeDialogOnScreen(dialog); 149 dialog.startEditSession(); 150 dialog.setVisible(true); 143 dialog.startEditSession(); 144 dialog.setVisible(true); 151 145 } 152 153 154 155 156 @Override 146 157 147 public void actionPerformed(ActionEvent e) { 158 148 launchEditor(); 159 149 } 160 150 161 162 @Override163 151 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 164 152 setEnabled(newSelection != null && newSelection.size() >0); 165 153 } 166 154 167 168 155 156 169 157 170 158 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/TagEditorDialog.java
r14338 r15319 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.plugins.tageditor; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 3 5 4 6 import java.awt.BorderLayout; … … 42 44 import org.openstreetmap.josm.plugins.tageditor.tagspec.ui.TabularTagSelector; 43 45 44 import static org.openstreetmap.josm.tools.I18n.tr;45 46 46 /** 47 47 * The dialog for editing name/value-pairs (aka <em>tags</em>) associated with {@link OsmPrimitive}s. … … 51 51 @SuppressWarnings("serial") 52 52 public class TagEditorDialog extends JDialog { 53 53 54 54 static private Logger logger = Logger.getLogger(TagEditorDialog.class.getName()); 55 55 56 56 /** the unique instance */ 57 57 static protected TagEditorDialog instance = null; 58 59 /** 60 * Access to the singleton instance 58 59 /** 60 * Access to the singleton instance 61 61 * 62 * @return the singleton instance of the dialog 62 * @return the singleton instance of the dialog 63 63 */ 64 64 static public TagEditorDialog getInstance() { … … 68 68 return instance; 69 69 } 70 71 72 /** 73 * default preferred size 70 71 72 /** 73 * default preferred size 74 74 */ 75 75 static public final Dimension PREFERRED_SIZE = new Dimension(700, 500); 76 77 78 /** the properties table */ 76 77 78 /** the properties table */ 79 79 private TagEditor tagEditor = null; 80 80 private TagEditorModel model = null; … … 82 82 /** the auto completion list viewer */ 83 83 private AutoCompletionListViewer aclViewer = null; 84 84 85 85 /** the cache of auto completion values used by the tag editor */ 86 86 private AutoCompletionCache acCache = null; 87 87 88 88 /** widgets */ 89 89 private JButton btnOK = null; 90 private JButton btnCancel = null; 90 private JButton btnCancel = null; 91 91 private JButton btnAdd = null; 92 92 private JButton btnDelete = null; … … 94 94 private CancelAction cancelAction = null; 95 95 96 96 97 97 public OKAction getOKAction() { 98 98 return okAction; 99 99 } 100 100 101 101 /** 102 102 * @return the tag editor model … … 106 106 } 107 107 108 109 108 109 110 110 protected JPanel buildButtonRow() { 111 111 // create the rows of action buttons at the bottom 112 // of the dialog 112 // of the dialog 113 113 // 114 114 JPanel pnl = new JPanel(); 115 115 pnl.setLayout(new FlowLayout(FlowLayout.RIGHT)); 116 117 // the ok button 116 117 // the ok button 118 118 // 119 119 okAction = new OKAction(); 120 120 btnOK = new JButton(okAction); 121 121 getModel().addPropertyChangeListener(okAction); 122 123 // the cancel button 122 123 // the cancel button 124 124 // 125 125 cancelAction = new CancelAction(); … … 127 127 pnl.add(btnOK); 128 128 pnl.add(btnCancel); 129 129 130 130 JPanel pnl1 = new JPanel(); 131 131 pnl.setLayout(new FlowLayout(FlowLayout.LEFT)); 132 132 133 133 // the add button 134 134 // 135 135 btnAdd = new JButton(tagEditor.getAddAction()); 136 136 btnDelete = new JButton(tagEditor.getDeleteAction()); 137 137 138 138 pnl1.add(btnAdd); 139 139 pnl1.add(btnDelete); 140 140 141 141 JPanel pnl2 = new JPanel(); 142 142 pnl2.setLayout(new BorderLayout()); 143 143 pnl2.add(pnl1, BorderLayout.WEST); 144 144 pnl2.add(pnl, BorderLayout.EAST); 145 146 return pnl2; 147 } 148 149 /** 150 * build the GUI 145 146 return pnl2; 147 } 148 149 /** 150 * build the GUI 151 151 */ 152 152 protected void build() { … … 158 158 setSize(PREFERRED_SIZE); 159 159 setTitle(tr("JOSM Tag Editor Plugin")); 160 161 160 161 162 162 // create tag editor and inject an instance of the tag 163 163 // editor model … … 165 165 tagEditor = new TagEditor(); 166 166 tagEditor.setTagEditorModel(model); 167 167 168 168 169 169 // create the auto completion list viewer and connect it 170 // to the tag editor 170 // to the tag editor 171 171 // 172 172 AutoCompletionList autoCompletionList = new AutoCompletionList(); … … 174 174 tagEditor.setAutoCompletionList(autoCompletionList); 175 175 tagEditor.setAutoCompletionCache(acCache); 176 aclViewer.addAutoCompletionListListener(tagEditor); 177 176 aclViewer.addAutoCompletionListListener(tagEditor); 177 178 178 JPanel pnlTagGrid = new JPanel(); 179 179 pnlTagGrid.setLayout(new BorderLayout()); … … 181 181 pnlTagGrid.add(aclViewer, BorderLayout.EAST); 182 182 pnlTagGrid.setBorder(BorderFactory.createEmptyBorder(5, 0,0,0)); 183 184 183 184 185 185 // create the preset selector 186 186 // … … 188 188 presetSelector.addPresetSelectorListener( 189 189 new IPresetSelectorListener() { 190 @Override191 190 public void itemSelected(Item item) { 192 191 tagEditor.stopEditing(); 193 192 model.applyPreset(item); 194 193 tagEditor.requestFocusInTopLeftCell(); 195 } 194 } 196 195 } 197 196 ); 198 199 197 198 200 199 JPanel pnlPresetSelector = new JPanel(); 201 200 pnlPresetSelector.setLayout(new BorderLayout()); … … 219 218 pnlTagSelector.add(tagSelector,BorderLayout.CENTER); 220 219 pnlTagSelector.setBorder(BorderFactory.createEmptyBorder(0,0,5,0 )); 221 222 223 224 225 // create the tabbed pane 220 221 222 223 224 // create the tabbed pane 226 225 // 227 226 JTabbedPane tabbedPane = new JTabbedPane(); 228 227 tabbedPane.add(pnlPresetSelector, tr("Presets")); 229 228 tabbedPane.add(pnlTagSelector, tr("Tags")); 230 229 231 230 // create split pane 232 231 // 233 232 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, 234 233 tabbedPane, pnlTagGrid); 235 234 splitPane.setOneTouchExpandable(true); 236 235 splitPane.setDividerLocation(200); 237 236 238 237 Dimension minimumSize = new Dimension(100, 50); 239 238 presetSelector.setMinimumSize(minimumSize); 240 239 pnlTagGrid.setMinimumSize(minimumSize); 241 240 242 241 getContentPane().add(splitPane,BorderLayout.CENTER); 243 242 244 243 getContentPane().add(buildButtonRow(), BorderLayout.SOUTH); 245 244 246 245 247 246 addWindowListener( 248 247 new WindowAdapter() { … … 253 252 getModel().ensureOneTag(); 254 253 tagEditor.clearSelection(); 255 tagEditor.requestFocusInTopLeftCell(); 256 } 254 tagEditor.requestFocusInTopLeftCell(); 255 } 257 256 }); 258 257 } 259 258 } 260 259 ); 261 262 260 261 263 262 // makes sure that 'Ctrl-Enter' in the properties table 264 263 // and in the aclViewer is handled by okAction 265 // 264 // 266 265 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)cancelAction.getValue(Action.ACCELERATOR_KEY), okAction.getValue(AbstractAction.NAME)); 267 266 getRootPane().getActionMap().put(cancelAction.getValue(Action.NAME), cancelAction); … … 270 269 getRootPane().getActionMap().put(okAction.getValue(Action.NAME), okAction); 271 270 272 273 // make sure the OK action is also enabled in sub components. I registered 271 272 // make sure the OK action is also enabled in sub components. I registered 274 273 // the action in the input and action maps of the dialogs root pane and I expected 275 274 // it to get triggered regardless of what subcomponent had focus, but it didn't. 276 // 275 // 277 276 aclViewer.installKeyAction(okAction); 278 277 aclViewer.installKeyAction(cancelAction); … … 280 279 presetSelector.installKeyAction(cancelAction); 281 280 } 282 283 284 281 282 283 285 284 /** 286 285 * constructor … … 289 288 acCache = new AutoCompletionCache(); 290 289 model = new TagEditorModel(); 291 build(); 292 } 293 294 290 build(); 291 } 292 293 295 294 @Override 296 295 public Dimension getPreferredSize() { … … 298 297 } 299 298 300 301 299 300 302 301 /** 303 302 * start an editing session. This method should be called before the dialog 304 * is shown on the screen, i.e. before {@link Dialog#setVisible(boolean)} is 305 * called. 306 */ 307 public void startEditSession() { 303 * is shown on the screen, i.e. before {@link Dialog#setVisible(boolean)} is 304 * called. 305 */ 306 public void startEditSession() { 308 307 model.clearAppliedPresets(); 309 model.initFromJOSMSelection(); 308 model.initFromJOSMSelection(); 310 309 acCache.initFromJOSMDataset(); 311 310 getModel().ensureOneTag(); 312 311 } 313 312 314 315 313 314 316 315 @SuppressWarnings("serial") 317 316 class CancelAction extends AbstractAction { 318 317 319 318 public CancelAction() { 320 319 putValue(Action.NAME, tr("Cancel")); 321 320 putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0)); 322 321 } 323 324 @Override 322 325 323 public void actionPerformed(ActionEvent arg0) { 326 324 setVisible(false); 327 } 328 } 329 330 331 325 } 326 } 327 328 329 332 330 @SuppressWarnings("serial") 333 331 class OKAction extends AbstractAction implements PropertyChangeListener { 334 332 335 333 public OKAction() { 336 334 putValue(Action.NAME, tr("OK")); 337 335 putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl ENTER")); 338 336 } 339 340 @Override 337 341 338 public void actionPerformed(ActionEvent e) { 342 339 run(); … … 347 344 setVisible(false); 348 345 model.updateJOSMSelection(); 349 350 Collection<OsmPrimitive> sel = Main.ds.getSelected(); 346 347 Collection<OsmPrimitive> sel = Main.ds.getSelected(); 351 348 DataSet.fireSelectionChanged(sel); 352 349 Main.parent.repaint(); // repaint all - drawing could have been changed 353 350 } 354 355 @Override 351 356 352 public void propertyChange(PropertyChangeEvent evt) { 357 if (! evt.getPropertyName().equals(TagEditorModel.PROP_DIRTY)) {353 if (! evt.getPropertyName().equals(TagEditorModel.PROP_DIRTY)) 358 354 return; 359 } 360 if (! evt.getNewValue().getClass().equals(Boolean.class)) { 355 if (! evt.getNewValue().getClass().equals(Boolean.class)) 361 356 return; 362 }363 357 boolean dirty = (Boolean)evt.getNewValue(); 364 358 setEnabled(dirty); 365 } 359 } 366 360 } 367 361 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionList.java
r14324 r15319 11 11 * AutoCompletionList manages a list of {@see AutoCompletionListItem}s. 12 12 * 13 * The list is sorted, items with higher priority first, then according to lexicographic order 14 * on the value of the {@see AutoCompletionListItem}. 13 * The list is sorted, items with higher priority first, then according to lexicographic order 14 * on the value of the {@see AutoCompletionListItem}. 15 15 * 16 16 * AutoCompletionList maintains two views on the list of {@see AutoCompletionListItem}s. 17 17 * <ol> 18 18 * <li>the bare, unfiltered view which includes all items</li> 19 * <li>a filtered view, which includes only items which match a current filter expression</li> 19 * <li>a filtered view, which includes only items which match a current filter expression</li> 20 20 * </ol> 21 21 * … … 28 28 29 29 /** the bare list of AutoCompletionItems */ 30 private ArrayList<AutoCompletionListItem> list = null; 31 /** the filtered list of AutoCompletionItems */ 32 private ArrayList<AutoCompletionListItem> filtered = null; 33 /** the filter expression */ 34 private String filter = null; 35 36 /** 37 * constructor 30 private ArrayList<AutoCompletionListItem> list = null; 31 /** the filtered list of AutoCompletionItems */ 32 private ArrayList<AutoCompletionListItem> filtered = null; 33 /** the filter expression */ 34 private String filter = null; 35 36 /** 37 * constructor 38 38 */ 39 39 public AutoCompletionList() { … … 41 41 filtered = new ArrayList<AutoCompletionListItem>(); 42 42 } 43 44 43 44 45 45 /** 46 46 * applies a filter expression to the list of {@see AutoCompletionListItem}s. 47 47 * 48 * The matching criterion is a case insensitive substring match. 48 * The matching criterion is a case insensitive substring match. 49 49 * 50 50 * @param filter the filter expression; must not be null … … 53 53 */ 54 54 public void applyFilter(String filter) { 55 if (filter == null) {55 if (filter == null) 56 56 throw new IllegalArgumentException("argument 'filter' must not be null"); 57 }58 57 this.filter = filter; 59 58 filter(); 60 59 } 61 62 /** 63 * clears the current filter 60 61 /** 62 * clears the current filter 64 63 * 65 64 */ … … 68 67 filter(); 69 68 } 70 71 /** 72 * @return the current filter expression; null, if no filter expression is set 69 70 /** 71 * @return the current filter expression; null, if no filter expression is set 73 72 */ 74 73 public String getFilter() { 75 return filter; 76 } 77 78 79 /** 74 return filter; 75 } 76 77 78 /** 80 79 * adds an AutoCompletionListItem to the list. Only adds the item if it 81 * is not null and if not in the list yet. 82 * 83 * @param item the item 80 * is not null and if not in the list yet. 81 * 82 * @param item the item 84 83 */ 85 84 public void add(AutoCompletionListItem item) { 86 if (item == null) { 87 return; 88 } 85 if (item == null) 86 return; 89 87 appendOrUpdatePriority(item); 90 88 sort(); 91 89 filter(); 92 90 } 93 94 91 92 95 93 /** 96 94 * adds another AutoCompletionList to this list. An item is only 97 * added it is not null and if it does not exist in the list yet. 95 * added it is not null and if it does not exist in the list yet. 98 96 * 99 97 * @param other another auto completion list; must not be null 100 * @exception IllegalArgumentException thrown, if other is null 98 * @exception IllegalArgumentException thrown, if other is null 101 99 */ 102 100 public void add(AutoCompletionList other) { 103 if (other == null) {101 if (other == null) 104 102 throw new IllegalArgumentException("argument 'other' must not be null"); 105 }106 103 for (AutoCompletionListItem item : other.list) { 107 104 appendOrUpdatePriority(item); … … 110 107 filter(); 111 108 } 112 113 109 110 114 111 /** 115 112 * adds a list of AutoCompletionListItem to this list. Only items which 116 * are not null and which do not exist yet in the list are added. 113 * are not null and which do not exist yet in the list are added. 117 114 * 118 115 * @param other a list of AutoCompletionListItem; must not be null 119 * @exception IllegalArgumentException thrown, if other is null 116 * @exception IllegalArgumentException thrown, if other is null 120 117 */ 121 118 public void add(List<AutoCompletionListItem> other) { 122 if (other == null) {119 if (other == null) 123 120 throw new IllegalArgumentException("argument 'other' must not be null"); 124 }125 121 for (AutoCompletionListItem toadd : other) { 126 122 appendOrUpdatePriority(toadd); … … 144 140 } 145 141 } 146 147 /** 148 * checks whether a specific item is already in the list. Matches for the 149 * the value <strong>and</strong> the priority of the item 142 143 /** 144 * checks whether a specific item is already in the list. Matches for the 145 * the value <strong>and</strong> the priority of the item 150 146 * 151 147 * @param item the item to check 152 * @return true, if item is in the list; false, otherwise 148 * @return true, if item is in the list; false, otherwise 153 149 */ 154 150 public boolean contains(AutoCompletionListItem item) { 155 if (item == null) { 156 return false; 157 } 151 if (item == null) 152 return false; 158 153 return list.contains(item); 159 154 } 160 155 161 156 /** 162 157 * checks whether an item with the given value is already in the list. Ignores 163 158 * priority of the items. 164 159 * 165 * @param value the value of an auto completion item 166 * @return true, if value is in the list; false, otherwise 160 * @param value the value of an auto completion item 161 * @return true, if value is in the list; false, otherwise 167 162 */ 168 163 public boolean contains(String value) { 169 if (value == null) { 170 return false; 171 } 164 if (value == null) 165 return false; 172 166 for (AutoCompletionListItem item: list) { 173 if (item.getValue().equals(value)) { 174 return true; 175 } 176 } 177 return false; 178 } 179 180 /** 181 * 182 * @param value a specific value 167 if (item.getValue().equals(value)) 168 return true; 169 } 170 return false; 171 } 172 173 /** 174 * 175 * @param value a specific value 183 176 * @return the auto completion item for this value; null, if there is no 184 * such auto completion item 177 * such auto completion item 185 178 */ 186 179 public AutoCompletionListItem lookup(String value) { 187 if (value == null) {180 if (value == null) 188 181 return null; 189 }190 182 for (AutoCompletionListItem item : list) { 191 if (item.getValue().equals(value)) {183 if (item.getValue().equals(value)) 192 184 return item; 193 }194 185 } 195 186 return null; 196 187 } 197 198 188 189 199 190 /** 200 191 * removes the auto completion item with key <code>key</code> 201 * @param key the key; 192 * @param key the key; 202 193 */ 203 194 public void remove(String key) { 204 if (key == null) { 205 return; 206 } 195 if (key == null) 196 return; 207 197 for (int i=0;i< list.size();i++) { 208 198 AutoCompletionListItem item = list.get(i); 209 199 if (item.getValue().equals(key)) { 210 200 list.remove(i); 211 return; 212 } 213 } 214 } 215 216 217 218 /** 219 * sorts the list 201 return; 202 } 203 } 204 } 205 206 207 208 /** 209 * sorts the list 220 210 */ 221 211 protected void sort() { 222 Collections.sort(list); 223 } 224 212 Collections.sort(list); 213 } 214 225 215 protected void filter() { 226 216 filtered.clear(); … … 231 221 for (AutoCompletionListItem item: list) { 232 222 filtered.add(item); 233 } 223 } 234 224 return; 235 225 } 236 226 237 227 // apply the pattern to list of possible values. If it matches, add the 238 // value to the list of filtered values 239 // 228 // value to the list of filtered values 229 // 240 230 for (AutoCompletionListItem item : list) { 241 231 if (item.getValue().startsWith(filter)) { … … 243 233 } 244 234 } 245 235 246 236 fireTableDataChanged(); 247 237 } 248 249 /** 250 * replies the number of filtered items 251 * 252 * @return the number of filtered items 238 239 /** 240 * replies the number of filtered items 241 * 242 * @return the number of filtered items 253 243 */ 254 244 public int getFilteredSize() { 255 245 return this.filtered.size(); 256 246 } 257 258 /** 259 * replies the idx-th item from the list of filtered items 247 248 /** 249 * replies the idx-th item from the list of filtered items 260 250 * @param idx the index; must be in the range 0<= idx < {@see #getFilteredSize()} 261 251 * @return the item … … 264 254 */ 265 255 public AutoCompletionListItem getFilteredItem(int idx) { 266 if (idx < 0 || idx >= getFilteredSize()) {256 if (idx < 0 || idx >= getFilteredSize()) 267 257 throw new IndexOutOfBoundsException("idx out of bounds. idx=" + idx); 268 }269 258 return filtered.get(idx); 270 259 } 271 272 260 261 273 262 /** 274 263 * removes all elements from the auto completion list … … 279 268 fireTableDataChanged(); 280 269 } 281 282 283 @Overridepublic int getColumnCount() {270 271 272 public int getColumnCount() { 284 273 return 1; 285 274 } 286 275 287 @Overridepublic int getRowCount() {288 289 290 291 292 @Overridepublic Object getValueAt(int rowIndex, int columnIndex) {276 public int getRowCount() { 277 278 return list == null ? 0 : getFilteredSize(); 279 } 280 281 public Object getValueAt(int rowIndex, int columnIndex) { 293 282 return list == null ? null : getFilteredItem(rowIndex); 294 295 283 } 284 296 285 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListItem.java
r14324 r15319 5 5 * Represents an entry in the list of auto completion values. 6 6 * 7 * An AutoCompletionListItem has a <em>priority</em> and a <em>value</em>. 8 * 7 * An AutoCompletionListItem has a <em>priority</em> and a <em>value</em>. 8 * 9 9 * The priority helps to sort the auto completion items according to their importance. For instance, 10 10 * in an auto completion list for tag names, standard tag names would be assigned a higher … … 12 12 * {@see AutoCompletionItemPritority}. 13 13 * 14 * The value is a string which will be displayed in the auto completion list. 14 * The value is a string which will be displayed in the auto completion list. 15 15 * 16 16 * @author gubaer … … 19 19 public class AutoCompletionListItem implements Comparable<AutoCompletionListItem>{ 20 20 21 /** the pritority of this item */ 21 /** the pritority of this item */ 22 22 private AutoCompletionItemPritority priority; 23 /** the value of this item */ 23 /** the value of this item */ 24 24 private String value; 25 25 26 26 /** 27 * constructor 27 * constructor 28 28 */ 29 29 public AutoCompletionListItem() { … … 31 31 priority = AutoCompletionItemPritority.UNKNOWN; 32 32 } 33 33 34 34 public AutoCompletionListItem(String value, AutoCompletionItemPritority priority) { 35 35 this.value = value; … … 39 39 /** 40 40 * 41 * @return the priority 41 * @return the priority 42 42 */ 43 43 public AutoCompletionItemPritority getPriority() { 44 45 44 return priority; 45 } 46 46 47 47 /** 48 * sets the priority 49 * @param priority the priority 48 * sets the priority 49 * @param priority the priority 50 50 */ 51 51 public void setPriority(AutoCompletionItemPritority priority) { 52 53 52 this.priority = priority; 53 } 54 54 55 55 /** 56 56 * 57 * @return the value 57 * @return the value 58 58 */ 59 59 public String getValue() { 60 61 60 return value; 61 } 62 62 63 63 /** 64 * sets the value 64 * sets the value 65 65 * @param value the value; must not be null 66 66 * @exception IllegalArgumentException thrown, if value if null 67 67 */ 68 68 public void setValue(String value) { 69 if (value == null) {69 if (value == null) 70 70 throw new IllegalArgumentException("argument 'value' must not be null"); 71 } 72 this.value = value; 73 } 71 this.value = value; 72 } 74 73 75 74 @Override public String toString() { … … 86 85 87 86 @Override public int hashCode() { 88 89 90 91 92 93 94 87 final int prime = 31; 88 int result = 1; 89 result = prime * result 90 + ((priority == null) ? 0 : priority.hashCode()); 91 result = prime * result + ((value == null) ? 0 : value.hashCode()); 92 return result; 93 } 95 94 96 95 @Override public boolean equals(Object obj) { 97 if (this == obj) 98 return true; 99 if (obj == null) 100 return false; 101 if (getClass() != obj.getClass()) 102 return false; 103 final AutoCompletionListItem other = (AutoCompletionListItem)obj; 104 if (priority == null) { 105 if (other.priority != null) 106 return false; 107 } else if (!priority.equals(other.priority)) 108 return false; 109 if (value == null) { 110 if (other.value != null) 111 return false; 112 } else if (!value.equals(other.value)) 113 return false; 114 return true; 115 } 116 117 118 @Override public int compareTo(AutoCompletionListItem other) { 119 int ret = this.priority.compareTo(other.priority); 120 if (ret != 0) { 121 return ret; 122 } else { 123 return this.value.compareTo(other.value); 124 } 96 if (this == obj) 97 return true; 98 if (obj == null) 99 return false; 100 if (getClass() != obj.getClass()) 101 return false; 102 final AutoCompletionListItem other = (AutoCompletionListItem)obj; 103 if (priority == null) { 104 if (other.priority != null) 105 return false; 106 } else if (!priority.equals(other.priority)) 107 return false; 108 if (value == null) { 109 if (other.value != null) 110 return false; 111 } else if (!value.equals(other.value)) 112 return false; 113 return true; 125 114 } 126 115 127 128 129 130 116 117 public int compareTo(AutoCompletionListItem other) { 118 int ret = this.priority.compareTo(other.priority); 119 if (ret != 0) 120 return ret; 121 else 122 return this.value.compareTo(other.value); 123 } 124 125 126 127 128 131 129 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListRenderer.java
r14324 r15319 13 13 * This is the table cell renderer for the list of auto completion list items. 14 14 * 15 * It uses an instance of {@Link JLabel} to render an {@link AutoCompletionListItem}. 15 * It uses an instance of {@Link JLabel} to render an {@link AutoCompletionListItem}. 16 16 * 17 17 * … … 23 23 static public final String RES_SELECTION_ICON = "/resources/selection.gif"; 24 24 public static final Color BG_COLOR_SELECTED = new Color(143,170,255); 25 25 26 26 /** the renderer component */ 27 private JLabel renderer;28 27 private final JLabel renderer; 28 29 29 /** the icon used to decorate items of priority 30 * {@link AutoCompletionItemPritority#IS_IN_STANDARD} 30 * {@link AutoCompletionItemPritority#IS_IN_STANDARD} 31 31 */ 32 32 private Icon iconStandard; 33 34 /** the icon used to decorate items of priority 33 34 /** the icon used to decorate items of priority 35 35 * {@link AutoCompletionItemPritority#IS_IN_SELECTION} 36 36 */ 37 37 private Icon iconSelection; 38 38 39 39 /** 40 * constructor 40 * constructor 41 41 */ 42 42 public AutoCompletionListRenderer() { 43 43 renderer = new JLabel(); 44 44 renderer.setOpaque(true); 45 45 46 46 loadIcons(); 47 47 } 48 48 49 49 /** 50 * loads the icons 50 * loads the icons 51 51 */ 52 52 protected void loadIcons() { 53 53 java.net.URL imgURL = getClass().getResource(RES_OSM_ICON); 54 55 56 57 58 59 60 54 if (imgURL != null) { 55 iconStandard = new ImageIcon(imgURL); 56 } else { 57 System.err.println("Could not load icon: " + RES_OSM_ICON); 58 iconStandard = null; 59 } 60 61 61 imgURL = getClass().getResource(RES_SELECTION_ICON); 62 63 64 65 66 67 62 if (imgURL != null) { 63 iconSelection = new ImageIcon(imgURL); 64 } else { 65 System.err.println("Could not load icon: " + RES_SELECTION_ICON); 66 iconSelection = null; 67 } 68 68 } 69 70 69 70 71 71 /** 72 * prepares the renderer for rendering a specific icon 72 * prepares the renderer for rendering a specific icon 73 73 * 74 * @param item the item to be rendered 74 * @param item the item to be rendered 75 75 */ 76 76 protected void prepareRendererIcon(AutoCompletionListItem item) { … … 85 85 } 86 86 } 87 87 88 88 /** 89 * resets the renderer 89 * resets the renderer 90 90 */ 91 91 protected void resetRenderer() { … … 96 96 renderer.setForeground(Color.BLACK); 97 97 } 98 98 99 99 /** 100 * prepares background and text colors for a selected item 100 * prepares background and text colors for a selected item 101 101 */ 102 102 protected void renderSelected() { … … 104 104 renderer.setForeground(Color.WHITE); 105 105 } 106 107 @Override 106 108 107 public Component getTableCellRendererComponent(JTable table, Object value, 109 108 boolean isSelected, boolean hasFocus, int row, int column) { 110 109 111 110 resetRenderer(); 112 // set icon and text 111 // set icon and text 113 112 // 114 113 if (value instanceof AutoCompletionListItem) { … … 121 120 renderer.setText("<null>"); 122 121 } 123 124 // prepare background and foreground for a selected item 122 123 // prepare background and foreground for a selected item 125 124 // 126 125 if (isSelected) { 127 126 renderSelected(); 128 127 } 129 130 128 129 131 130 return renderer; 132 131 133 132 } 134 133 135 136 134 135 137 136 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetItemListCellRenderer.java
r14325 r15319 1 1 package org.openstreetmap.josm.plugins.tageditor.editor; 2 3 import static org.openstreetmap.josm.tools.I18n.tr; 2 4 3 5 import java.awt.Color; … … 11 13 12 14 import org.openstreetmap.josm.plugins.tageditor.preset.Item; 13 import static org.openstreetmap.josm.tools.I18n.tr;14 15 15 16 public class PresetItemListCellRenderer extends JLabel implements 16 17 ListCellRenderer { 17 18 18 19 private static final Logger logger = Logger.getLogger(PresetItemListCellRenderer.class.getName()); 19 20 private static final Font DEFAULT_FONT = new Font("SansSerif",Font.PLAIN,10); 20 21 public static final Color BG_COLOR_SELECTED = new Color(143,170,255); 21 22 @Override 22 23 23 public Component getListCellRendererComponent(JList list, Object value, 24 24 int index, boolean isSelected, boolean cellHasFocus) { 25 26 25 27 26 Item item = (Item)value; 28 27 if (item == null) { … … 38 37 StringBuilder sb = new StringBuilder(); 39 38 sb.append(item.getParent().getName()) 40 41 39 .append("/") 40 .append(item.getName()); 42 41 setText(sb.toString()); 43 42 setOpaque(true); -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetManager.java
r14338 r15319 1 1 package org.openstreetmap.josm.plugins.tageditor.editor; 2 3 import static org.openstreetmap.josm.tools.I18n.tr; 2 4 3 5 import java.awt.Dimension; … … 14 16 15 17 import org.openstreetmap.josm.plugins.tageditor.preset.Item; 16 import static org.openstreetmap.josm.tools.I18n.tr;17 18 18 19 public class PresetManager extends JPanel { 19 20 20 21 static private Logger logger = Logger.getLogger(PresetManager.class.getName()); 21 22 22 23 private JComboBox presets; 23 private JButton btnRemove; 24 private JButton btnRemove; 24 25 private JButton btnHighlight; 25 26 private TagEditorModel model = null; 26 27 27 28 protected void build() { 28 29 setLayout(new FlowLayout(FlowLayout.LEFT)); 29 30 30 31 // create the combobox to display the list of applied presets 31 32 // … … 38 39 } 39 40 }; 40 41 41 42 presets.addItemListener( 42 new ItemListener(){43 @Override44 public void itemStateChanged(ItemEvent e) {45 syncWidgetStates();43 new ItemListener(){ 44 public void itemStateChanged(ItemEvent e) { 45 syncWidgetStates(); 46 } 46 47 } 47 }48 48 ); 49 49 50 50 presets.setRenderer(new PresetItemListCellRenderer()); 51 51 add(presets); 52 52 53 53 btnHighlight = new JButton(tr("Highlight")); 54 54 btnHighlight.addActionListener( 55 55 new ActionListener() { 56 @Override57 56 public void actionPerformed(ActionEvent arg0) { 58 57 highlightCurrentPreset(); 59 58 } 60 59 } 61 62 60 ); 61 63 62 add(btnHighlight); 64 63 65 64 btnRemove = new JButton(tr("Remove")); 66 65 btnRemove.addActionListener( 67 new ActionListener() {68 @Override69 public void actionPerformed(ActionEvent arg0) {70 removeCurrentPreset();66 new ActionListener() { 67 public void actionPerformed(ActionEvent arg0) { 68 removeCurrentPreset(); 69 } 71 70 } 72 }73 71 ); 74 72 … … 76 74 syncWidgetStates(); 77 75 } 78 76 79 77 protected void syncWidgetStates() { 80 78 btnRemove.setEnabled(presets.getSelectedItem() != null); 81 79 btnHighlight.setEnabled(presets.getSelectedItem() != null); 82 80 } 83 81 84 82 protected void removeCurrentPreset() { 85 83 Item item= (Item)presets.getSelectedItem(); … … 88 86 } 89 87 } 90 88 91 89 protected void highlightCurrentPreset() { 92 90 model.highlightCurrentPreset(); 93 91 } 94 92 95 93 public PresetManager() { 96 94 build(); 97 95 } 98 96 99 97 public void setModel(TagEditorModel model) { 100 98 presets.setModel(model.getAppliedPresetsModel()); 101 99 this.model = model; 102 100 } 103 104 105 101 102 103 106 104 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/RunnableAction.java
r14325 r15319 7 7 public abstract class RunnableAction extends AbstractAction implements Runnable { 8 8 9 public RunnableAction() { 9 public RunnableAction() { 10 10 } 11 11 12 @Override13 12 public abstract void run(); 14 13 15 @Override16 14 public void actionPerformed(ActionEvent arg0) { 17 run(); 15 run(); 18 16 } 19 17 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TableCellEditor.java
r14520 r15319 3 3 4 4 import java.awt.Component; 5 import java.util.Collection;6 5 import java.util.logging.Level; 7 6 import java.util.logging.Logger; … … 10 9 import javax.swing.JTable; 11 10 12 import org.openstreetmap.josm.Main;13 import org.openstreetmap.josm.data.osm.OsmPrimitive;14 11 import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionCache; 15 12 import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionContext; … … 28 25 @SuppressWarnings("serial") 29 26 public class TableCellEditor extends AbstractCellEditor implements javax.swing.table.TableCellEditor, IAutoCompletionListListener{ 30 27 31 28 /** the logger object */ 32 29 static private Logger logger = Logger.getLogger(TableCellEditor.class.getName()); … … 39 36 /** the cache of auto completion items derived from the current JOSM data set */ 40 37 private AutoCompletionCache acCache = null; 41 38 42 39 /** user input is matched against this list of auto completion items */ 43 40 private AutoCompletionList autoCompletionList = null; 44 45 46 /** 47 * constructor 41 42 43 /** 44 * constructor 48 45 */ 49 46 public TableCellEditor() { … … 51 48 acCache = new AutoCompletionCache(); 52 49 } 53 50 54 51 /** 55 52 * initializes the auto completion list when the table cell editor starts 56 * to edit the key of a tag. In this case the auto completion list is 53 * to edit the key of a tag. In this case the auto completion list is 57 54 * initialized with the set of standard key values and the set of current key 58 * values from the the current JOSM data set. Keys already present in the 55 * values from the the current JOSM data set. Keys already present in the 59 56 * current tag model are removed from the auto completion list. 60 * 61 * @param model the tag editor model 62 * @param currentTag the current tag 57 * 58 * @param model the tag editor model 59 * @param currentTag the current tag 63 60 */ 64 61 protected void initAutoCompletionListForKeys(TagEditorModel model, TagModel currentTag) { 65 62 AutoCompletionContext context = new AutoCompletionContext(); 66 63 context.initFromJOSMSelection(); 67 64 68 65 if (autoCompletionList == null) { 69 66 logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor."); 70 67 return; 71 68 } 72 69 73 70 autoCompletionList.clear(); 74 75 // add the list of standard keys 71 72 // add the list of standard keys 76 73 // 77 74 try { … … 80 77 logger.log(Level.WARNING, "failed to initialize auto completion list with standard keys.", e); 81 78 } 82 83 84 79 80 81 85 82 // add the list of keys in the current data set 86 83 // … … 90 87 ); 91 88 } 92 89 93 90 // remove the keys already present in the current tag model 94 91 // … … 100 97 autoCompletionList.fireTableDataChanged(); 101 98 } 102 103 99 100 104 101 /** 105 102 * initializes the auto completion list when the cell editor starts to edit … … 108 105 * current data set for the given key. 109 106 * 110 * @param forKey the key 107 * @param forKey the key 111 108 */ 112 109 protected void initAutoCompletionListForValues(String forKey) { 113 110 114 111 if (autoCompletionList == null) { 115 112 logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor."); 116 113 return; 117 } 114 } 118 115 autoCompletionList.clear(); 119 116 AutoCompletionContext context = new AutoCompletionContext(); 120 117 context.initFromJOSMSelection(); 121 118 122 119 // add the list of standard values for the given key 123 120 // … … 129 126 logger.log(Level.WARNING, "failed to initialize auto completion list with standard values", e); 130 127 } 131 128 132 129 for (String value : acCache.getValues(forKey)) { 133 130 autoCompletionList.add( … … 135 132 ); 136 133 } 137 134 138 135 // add the list of possible values for a key from the current selection 139 136 // … … 142 139 //logger.info("adding ac item " + value + " with priority IN_SELECTION");; 143 140 autoCompletionList.add( 144 new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_SELECTION) 141 new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_SELECTION) 145 142 ); 146 143 } 147 144 } 148 145 } 149 150 151 /** 152 * replies the table cell editor 153 */ 154 @Override public Component getTableCellEditorComponent(JTable table, 155 Object value, boolean isSelected, int row, int column) { 156 currentTag = (TagModel) value; 157 158 if (column == 0) { 159 editor.setText(currentTag.getName()); 160 currentColumn = 0; 161 TagEditorModel model = (TagEditorModel)table.getModel(); 162 initAutoCompletionListForKeys(model, currentTag); 163 return editor; 164 } else if (column == 1) { 165 166 if (currentTag.getValueCount() == 0) { 167 editor.setText(""); 168 } else if (currentTag.getValueCount() == 1) { 169 editor.setText(currentTag.getValues().get(0)); 170 } else { 171 editor.setText(""); 172 } 173 currentColumn = 1; 174 initAutoCompletionListForValues(currentTag.getName()); 175 return editor; 146 147 148 /** 149 * replies the table cell editor 150 */ 151 public Component getTableCellEditorComponent(JTable table, 152 Object value, boolean isSelected, int row, int column) { 153 currentTag = (TagModel) value; 154 155 if (column == 0) { 156 editor.setText(currentTag.getName()); 157 currentColumn = 0; 158 TagEditorModel model = (TagEditorModel)table.getModel(); 159 initAutoCompletionListForKeys(model, currentTag); 160 return editor; 161 } else if (column == 1) { 162 163 if (currentTag.getValueCount() == 0) { 164 editor.setText(""); 165 } else if (currentTag.getValueCount() == 1) { 166 editor.setText(currentTag.getValues().get(0)); 176 167 } else { 177 logger.warning("column this table cell editor is requested for is out of range. column=" + column); 178 return null; 179 } 180 } 181 182 183 @Override 168 editor.setText(""); 169 } 170 currentColumn = 1; 171 initAutoCompletionListForValues(currentTag.getName()); 172 return editor; 173 } else { 174 logger.warning("column this table cell editor is requested for is out of range. column=" + column); 175 return null; 176 } 177 } 178 184 179 public Object getCellEditorValue() { 185 180 return editor.getText(); 186 } 187 188 189 181 } 182 190 183 @Override 191 184 public void cancelCellEditing() { … … 198 191 logger.warning("no tag editor model set. Can't update edited values. Please set tag editor model first"); 199 192 return super.stopCellEditing(); 200 201 193 } 194 202 195 if (currentColumn == 0) { 203 196 tagEditorModel.updateTagName(currentTag, editor.getText()); 204 197 } else if (currentColumn == 1){ 205 198 if (currentTag.getValueCount() > 1 && ! editor.getText().equals("")) { 206 tagEditorModel.updateTagValue(currentTag, editor.getText()); 199 tagEditorModel.updateTagValue(currentTag, editor.getText()); 207 200 } else if (currentTag.getValueCount() <= 1) { 208 201 tagEditorModel.updateTagValue(currentTag, editor.getText()); 209 202 } 210 203 } 211 212 return super.stopCellEditing(); 204 205 return super.stopCellEditing(); 213 206 } 214 207 … … 216 209 * replies the {@link AutoCompletionList} this table cell editor synchronizes with 217 210 * 218 * @return the auto completion list 211 * @return the auto completion list 219 212 */ 220 213 public AutoCompletionList getAutoCompletionList() { 221 222 223 224 /** 225 * sets the {@link AutoCompletionList} this table cell editor synchronizes with 226 * @param autoCompletionList the auto completion list 214 return autoCompletionList; 215 } 216 217 /** 218 * sets the {@link AutoCompletionList} this table cell editor synchronizes with 219 * @param autoCompletionList the auto completion list 227 220 */ 228 221 public void setAutoCompletionList(AutoCompletionList autoCompletionList) { 229 230 231 232 222 this.autoCompletionList = autoCompletionList; 223 editor.setAutoCompletionList(autoCompletionList); 224 } 225 233 226 public void setAutoCompletionCache(AutoCompletionCache acCache) { 234 227 this.acCache = acCache; 235 228 } 236 237 238 239 @Override 229 240 230 public void autoCompletionItemSelected(String item) { 241 231 editor.setText(item); … … 243 233 editor.requestFocus(); 244 234 } 245 235 246 236 public TagFieldEditor getEditor() { 247 237 return editor; 248 238 } 249 239 250 240 /** 251 241 * sets the tag editor model 252 * 253 * @param tagEditorModel the tag editor model 242 * 243 * @param tagEditorModel the tag editor model 254 244 */ 255 245 public void setTagEditorModel(TagEditorModel tagEditorModel) { 256 246 this.tagEditorModel = tagEditorModel; 257 247 } 258 248 259 249 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditor.java
r14520 r15319 11 11 import javax.swing.ScrollPaneConstants; 12 12 13 14 13 import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionCache; 15 14 import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionList; … … 20 19 * TagEditor is a {@link JPanel} which consists of a two sub panels: 21 20 * <ul> 22 * <li>a small area in which a drop-down box with a list of presets is displayed. 21 * <li>a small area in which a drop-down box with a list of presets is displayed. 23 22 * Two buttons allow to highlight and remove a presets respectively.</li> 24 23 * <li>the main table with the tag names and tag values … … 30 29 * <li>an instance of {@link TagEditorModel} - use {@see #setTagEditorModel(TagEditorModel)}</li> 31 30 * <li>an instance of {@link AutoCompletionCache} - inject it using {@see #setAutoCompletionCache(AutoCompletionCache)}. 32 * The table cell editor used by the table in this component uses the AutoCompletionCache in order to 31 * The table cell editor used by the table in this component uses the AutoCompletionCache in order to 33 32 * build up a list of auto completion values from the current data set</li> 34 33 * <li>an instance of {@link AutoCompletionList} - inject it using {@see #setAutoCompletionList(AutoCompletionList)}. 35 34 * The table cell editor used by the table in this component uses the AutoCompletionList 36 * to build up a list of auto completion values from the set of standardized 35 * to build up a list of auto completion values from the set of standardized 37 36 * OSM tags</li> 38 37 * </ul>O … … 41 40 * <pre> 42 41 * AutoCompletionList autoCompletionList = .... // init the autocompletion list 43 * AutoCompletionCache autoCompletionCache = ... // init the auto completion cache 44 * TagEditorModel model = ... // init the tag editor model 45 * 42 * AutoCompletionCache autoCompletionCache = ... // init the auto completion cache 43 * TagEditorModel model = ... // init the tag editor model 44 * 46 45 * TagEditor tagEditor = new TagEditor(); 47 46 * tagEditor.setTagEditorModel(model); 48 47 * tagEditor.setAutoCompletionList(autoCompletionList); 49 * tagEditor.setAutoCompletionCache(autoCompletionCache); 48 * tagEditor.setAutoCompletionCache(autoCompletionCache); 50 49 * </pre> 51 50 */ … … 53 52 54 53 private static final Logger logger = Logger.getLogger(TagEditor.class.getName()); 55 56 private TagEditorModel tagEditorModel;54 55 private final TagEditorModel tagEditorModel; 57 56 private TagTable tblTagEditor; 58 57 private PresetManager presetManager; 59 58 private AutoCompletionList autoCompletionList; 60 61 59 60 62 61 /** 63 62 * builds the GUI … … 66 65 protected void build() { 67 66 setLayout(new BorderLayout()); 68 67 69 68 // build the scrollable table for editing tag names and tag values 70 69 // … … 74 73 scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 75 74 add(scrollPane, BorderLayout.CENTER); 76 75 77 76 // this adapters ensures that the width of the tag table columns is adjusted 78 // to the width of the scroll pane viewport. Also tried to overwrite 77 // to the width of the scroll pane viewport. Also tried to overwrite 79 78 // getPreferredViewportSize() in JTable, but did not work. 80 79 // … … 82 81 new ComponentAdapter() { 83 82 @Override public void componentResized(ComponentEvent e) { 84 85 86 87 83 super.componentResized(e); 84 Dimension d = scrollPane.getViewport().getExtentSize(); 85 tblTagEditor.adjustColumnWidth(d.width); 86 } 88 87 } 89 88 ); 90 91 // build the preset manager which shows a list of applied presets 92 // 89 90 // build the preset manager which shows a list of applied presets 91 // 93 92 presetManager = new PresetManager(); 94 93 presetManager.setModel(tagEditorModel); 95 94 add(presetManager, BorderLayout.NORTH); 96 95 } 97 98 96 97 99 98 /** 100 * constructor 99 * constructor 101 100 */ 102 101 public TagEditor() { 103 // creates a default model and a default cache 102 // creates a default model and a default cache 104 103 // 105 tagEditorModel = new TagEditorModel(); 106 104 tagEditorModel = new TagEditorModel(); 105 107 106 build(); 108 107 } 109 108 110 109 111 110 /** 112 * replies the tag editor model 113 * @return the tag editor model 111 * replies the tag editor model 112 * @return the tag editor model 114 113 */ 115 114 public TagEditorModel getTagEditorModel() { … … 120 119 * sets the tag editor model 121 120 * 122 * @param tagEditorModel the tag editor model 121 * @param tagEditorModel the tag editor model 123 122 */ 124 123 public void setTagEditorModel(TagEditorModel tagEditorModel) { … … 132 131 presetManager.setModel(tagEditorModel); 133 132 } 134 133 135 134 public RunnableAction getDeleteAction() { 136 135 return tblTagEditor.getDeleteAction(); 137 136 } 138 137 139 138 public RunnableAction getAddAction() { 140 139 return tblTagEditor.getAddAction(); 141 140 } 142 143 144 141 142 143 145 144 public void clearSelection() { 146 145 tblTagEditor.getSelectionModel().clearSelection(); 147 146 } 148 149 147 150 148 149 151 150 public void stopEditing() { 152 151 TableCellEditor editor = (TableCellEditor) tblTagEditor.getCellEditor(); … … 155 154 } 156 155 } 157 158 156 157 159 158 public AutoCompletionList getAutoCompletionList() { 160 159 return ((org.openstreetmap.josm.plugins.tageditor.editor.TableCellEditor)tblTagEditor.getCellEditor()).getAutoCompletionList(); … … 164 163 tblTagEditor.setAutoCompletionList(autoCompletionList); 165 164 } 166 165 167 166 public void setAutoCompletionCache(AutoCompletionCache acCache) { 168 167 tblTagEditor.setAutoCompletionCache(acCache); 169 168 } 170 169 171 @Override 170 172 171 public void autoCompletionItemSelected(String item) { 173 172 org.openstreetmap.josm.plugins.tageditor.editor.TableCellEditor editor = ((org.openstreetmap.josm.plugins.tageditor.editor.TableCellEditor)tblTagEditor.getCellEditor()); … … 180 179 tblTagEditor.requestFocusInCell(0,0); 181 180 } 182 183 184 185 186 187 181 182 183 184 185 186 188 187 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditorModel.java
r14520 r15319 13 13 14 14 import javax.swing.DefaultComboBoxModel; 15 import javax.swing.SwingUtilities;16 15 import javax.swing.table.AbstractTableModel; 17 16 … … 27 26 28 27 /** 29 * TagEditorModel is a table model. 30 * 28 * TagEditorModel is a table model. 29 * 31 30 * 32 31 * @author gubaer … … 36 35 public class TagEditorModel extends AbstractTableModel { 37 36 static private final Logger logger = Logger.getLogger(TagEditorModel.class.getName()); 38 39 static public final String PROP_DIRTY = TagEditorModel.class.getName() + ".dirty"; 40 37 38 static public final String PROP_DIRTY = TagEditorModel.class.getName() + ".dirty"; 39 41 40 /** the list holding the tags */ 42 private ArrayList<TagModel> tags = null; 41 private ArrayList<TagModel> tags = null; 43 42 private ArrayList<Item> items = null; 44 43 45 44 /** indicates whether the model is dirty */ 46 private boolean dirty = false; 45 private boolean dirty = false; 47 46 private PropertyChangeSupport propChangeSupport = null; 48 47 49 48 private DefaultComboBoxModel appliedPresets = null; 50 49 51 50 52 51 /** 53 52 * constructor … … 63 62 propChangeSupport.addPropertyChangeListener(listener); 64 63 } 65 64 66 65 public void removeProperyChangeListener(PropertyChangeListener listener) { 67 66 propChangeSupport.removePropertyChangeListener(listener); 68 67 } 69 68 70 69 protected void fireDirtyStateChanged(final boolean oldValue, final boolean newValue) { 71 70 propChangeSupport.firePropertyChange(PROP_DIRTY, oldValue, newValue); 72 71 } 73 72 74 73 protected void setDirty(boolean newValue) { 75 74 boolean oldValue = dirty; … … 79 78 } 80 79 } 81 82 @Overridepublic int getColumnCount() {83 84 85 86 @Overridepublic int getRowCount() {87 88 89 90 @Overridepublic Object getValueAt(int rowIndex, int columnIndex) {91 if (rowIndex >= getRowCount()) {80 81 public int getColumnCount() { 82 return 2; 83 } 84 85 public int getRowCount() { 86 return tags.size(); 87 } 88 89 public Object getValueAt(int rowIndex, int columnIndex) { 90 if (rowIndex >= getRowCount()) 92 91 throw new IndexOutOfBoundsException("unexpected rowIndex: rowIndex=" + rowIndex); 93 } 94 92 95 93 TagModel tag = tags.get(rowIndex); 96 94 switch(columnIndex) { 97 95 case 0: 98 case 1: return tag; 99 100 default: 96 case 1: return tag; 97 98 default: 101 99 throw new IndexOutOfBoundsException("unexpected columnIndex: columnIndex=" + columnIndex); 102 } 103 104 105 106 /** 107 * removes all tags in the model 100 } 101 } 102 103 104 /** 105 * removes all tags in the model 108 106 */ 109 107 public void clear() { … … 113 111 fireTableDataChanged(); 114 112 } 115 113 116 114 /** 117 115 * adds a tag to the model … … 122 120 */ 123 121 public void add(TagModel tag) { 124 if (tag == null) {122 if (tag == null) 125 123 throw new IllegalArgumentException("argument 'tag' must not be null"); 126 }127 124 tags.add(tag); 128 125 setDirty(true); 129 126 fireTableDataChanged(); 130 127 } 131 132 128 129 133 130 public void prepend(TagModel tag) { 134 if (tag == null) {131 if (tag == null) 135 132 throw new IllegalArgumentException("argument 'tag' must not be null"); 136 }137 133 tags.add(0, tag); 138 134 setDirty(true); 139 135 fireTableDataChanged(); 140 136 } 141 142 143 /** 144 * adds a tag given by a name/value pair to the tag editor model. 137 138 139 /** 140 * adds a tag given by a name/value pair to the tag editor model. 145 141 * 146 142 * If there is no tag with name <code>name</name> yet, a new {@link TagModel} is created 147 143 * and append to this model. 148 144 * 149 * If there is a tag with name <code>name</name>, <code>value</code> is merged to the list 150 * of values for this tag. 145 * If there is a tag with name <code>name</name>, <code>value</code> is merged to the list 146 * of values for this tag. 151 147 * 152 148 * @param name the name; converted to "" if null … … 156 152 name = (name == null) ? "" : name; 157 153 value = (value == null) ? "" : value; 158 154 159 155 TagModel tag = get(name); 160 156 if (tag == null) { … … 163 159 } else { 164 160 tag.addValue(value); 165 } 166 setDirty(true); 167 } 168 169 170 /** 171 * replies the tag with name <code>name</code>; null, if no such tag exists 172 * @param name the tag name 173 * @return the tag with name <code>name</code>; null, if no such tag exists 161 } 162 setDirty(true); 163 } 164 165 166 /** 167 * replies the tag with name <code>name</code>; null, if no such tag exists 168 * @param name the tag name 169 * @return the tag with name <code>name</code>; null, if no such tag exists 174 170 */ 175 171 public TagModel get(String name) { 176 172 name = (name == null) ? "" : name; 177 173 for (TagModel tag : tags) { 178 if (tag.getName().equals(name)) { 179 return tag; 180 } 181 } 182 return null; 183 } 184 174 if (tag.getName().equals(name)) 175 return tag; 176 } 177 return null; 178 } 179 185 180 public TagModel get(int idx) { 186 181 TagModel tagModel = tags.get(idx); … … 189 184 190 185 191 186 192 187 @Override public boolean isCellEditable(int row, int col) { 193 188 // all cells are editable 194 189 return true; 195 196 197 198 /** 199 * deletes the names of the tags given by tagIndices 200 * 201 * @param tagIndices a list of tag indices 190 } 191 192 193 /** 194 * deletes the names of the tags given by tagIndices 195 * 196 * @param tagIndices a list of tag indices 202 197 */ 203 198 public void deleteTagNames(int [] tagIndices) { 204 if (tags == null) { 205 return; 206 } 199 if (tags == null) 200 return; 207 201 for (int tagIdx : tagIndices) { 208 202 TagModel tag = tags.get(tagIdx); … … 218 212 * deletes the values of the tags given by tagIndices 219 213 * 220 * @param tagIndices the lit of tag indices 214 * @param tagIndices the lit of tag indices 221 215 */ 222 216 public void deleteTagValues(int [] tagIndices) { 223 if (tags == null) { 224 return; 225 } 217 if (tags == null) 218 return; 226 219 for (int tagIdx : tagIndices) { 227 220 TagModel tag = tags.get(tagIdx); … … 233 226 setDirty(true); 234 227 } 235 228 236 229 /** 237 230 * deletes the tags given by tagIndices 238 231 * 239 * @param tagIndices the list of tag indices 232 * @param tagIndices the list of tag indices 240 233 */ 241 234 public void deleteTags(int [] tagIndices) { 242 if (tags == null) { 243 return; 244 } 235 if (tags == null) 236 return; 245 237 ArrayList<TagModel> toDelete = new ArrayList<TagModel>(); 246 238 for (int tagIdx : tagIndices) { … … 256 248 setDirty(true); 257 249 } 258 259 260 /** 261 * creates a new tag and appends it to the model 250 251 252 /** 253 * creates a new tag and appends it to the model 262 254 */ 263 255 public void appendNewTag() { … … 269 261 270 262 /** 271 * makes sure the model includes at least one (empty) tag 263 * makes sure the model includes at least one (empty) tag 272 264 */ 273 265 public void ensureOneTag() { … … 276 268 } 277 269 } 278 270 279 271 /** 280 272 * initializes the model with the tags in the current JOSM selection … … 292 284 setDirty(false); 293 285 } 294 295 296 /** 297 * checks whether the tag model includes a tag with a given key 298 * 299 * @param key the key 300 * @return true, if the tag model includes the tag; false, otherwise 286 287 288 /** 289 * checks whether the tag model includes a tag with a given key 290 * 291 * @param key the key 292 * @return true, if the tag model includes the tag; false, otherwise 301 293 */ 302 294 public boolean includesTag(String key) { 303 if (key == null) return false; 295 if (key == null) return false; 304 296 for (TagModel tag : tags) { 305 if (tag.getName().equals(key)) { 306 return true; 307 } 297 if (tag.getName().equals(key)) 298 return true; 308 299 } 309 300 return false; 310 301 } 311 302 312 303 313 304 protected Command createUpdateTagCommand(Collection<OsmPrimitive> primitives, TagModel tag) { 314 305 315 306 // tag still holds an unchanged list of different values for the same key. 316 // no property change command required 317 if (tag.getValueCount() > 1) {307 // no property change command required 308 if (tag.getValueCount() > 1) 318 309 return null; 319 } 320 321 // tag name holds an empty key. Don't apply it to the selection. 322 // 323 if (tag.getName().trim().equals("")) { 324 return null; 325 } 326 310 311 // tag name holds an empty key. Don't apply it to the selection. 312 // 313 if (tag.getName().trim().equals("")) 314 return null; 315 327 316 String newkey = tag.getName(); 328 317 String newvalue = tag.getValue(); 329 318 330 319 ChangePropertyCommand command = new ChangePropertyCommand(primitives,newkey, newvalue); 331 return command; 332 } 333 320 return command; 321 } 322 334 323 protected Command createDeleteTagsCommand(Collection<OsmPrimitive> primitives) { 335 324 336 325 List<String> currentkeys = getKeys(); 337 326 ArrayList<Command> commands = new ArrayList<Command>(); 338 327 339 328 for (OsmPrimitive primitive : primitives) { 340 329 if (primitive.keys == null) { … … 343 332 for (String oldkey : primitive.keys.keySet()) { 344 333 if (!currentkeys.contains(oldkey)) { 345 ChangePropertyCommand deleteCommand = 334 ChangePropertyCommand deleteCommand = 346 335 new ChangePropertyCommand(primitive,oldkey,null); 347 336 commands.add(deleteCommand); … … 349 338 } 350 339 } 351 340 352 341 SequenceCommand command = new SequenceCommand( 353 trn("Remove old keys from up to {0} object", "Remove old keys from up to {0} objects", primitives.size(), primitives.size()),354 commands342 trn("Remove old keys from up to {0} object", "Remove old keys from up to {0} objects", primitives.size(), primitives.size()), 343 commands 355 344 ); 356 345 357 346 return command; 358 347 } 359 348 360 349 /** 361 350 * updates the tags of the primitives in the current selection with the 362 * values in the current tag model 351 * values in the current tag model 363 352 * 364 353 */ … … 366 355 ArrayList<Command> commands = new ArrayList<Command>(); 367 356 Collection<OsmPrimitive> selection = Main.ds.getSelected(); 368 if (selection == null) { 369 return; 370 } 357 if (selection == null) 358 return; 371 359 for (TagModel tag : tags) { 372 360 Command command = createUpdateTagCommand(selection,tag); … … 379 367 commands.add(deleteCommand); 380 368 } 381 369 382 370 SequenceCommand command = new SequenceCommand( 383 trn("Updating properties of up to {0} object", "Updating properties of up to {0} objects", selection.size(), selection.size()),384 commands371 trn("Updating properties of up to {0} object", "Updating properties of up to {0} objects", selection.size(), selection.size()), 372 commands 385 373 ); 386 374 387 375 // executes the commands and adds them to the undo/redo chains 388 376 Main.main.undoRedo.add(command); 389 377 } 390 391 378 379 392 380 /** 393 381 * replies the list of keys of the tags managed by this model … … 404 392 return keys; 405 393 } 406 407 /** 408 * sorts the current tags according alphabetical order of names 394 395 /** 396 * sorts the current tags according alphabetical order of names 409 397 */ 410 398 protected void sort() { … … 412 400 tags, 413 401 new Comparator<TagModel>() { 414 @Override415 402 public int compare(TagModel self, TagModel other) { 416 403 return self.getName().compareTo(other.getName()); 417 } 404 } 418 405 } 419 406 ); 420 407 } 421 408 422 423 424 425 /** 426 * applies the tags defined for a preset item to the tag model. 427 * 428 * Mandatory tags are added to the list of currently edited tags. 429 * Optional tags are not added. 430 * The model remembers the currently applied presets. 409 410 411 412 /** 413 * applies the tags defined for a preset item to the tag model. 414 * 415 * Mandatory tags are added to the list of currently edited tags. 416 * Optional tags are not added. 417 * The model remembers the currently applied presets. 431 418 * 432 419 * @param item the preset item. Must not be null. … … 435 422 */ 436 423 public void applyPreset(Item item) { 437 if (item == null) {424 if (item == null) 438 425 throw new IllegalArgumentException("argument 'item' must not be null"); 439 }440 426 // check whether item is already applied 441 427 // 442 428 for(int i=0; i < appliedPresets.getSize(); i++) { 443 if (appliedPresets.getElementAt(i).equals(item)) {444 // abort - preset already applied 429 if (appliedPresets.getElementAt(i).equals(item)) 430 // abort - preset already applied 445 431 return; 446 } 447 } 448 449 // apply the tags proposed by the preset 432 } 433 434 // apply the tags proposed by the preset 450 435 // 451 436 for(Tag tag : item.getTags()) { … … 466 451 } 467 452 } 468 453 469 454 // remember the preset and make it the current preset 470 455 // … … 473 458 fireTableDataChanged(); 474 459 } 475 476 460 461 477 462 /** 478 463 * applies a tag given by a {@see KeyValuePair} to the model 479 464 * 480 * @param pair the key value pair 465 * @param pair the key value pair 481 466 */ 482 467 public void applyKeyValuePair(KeyValuePair pair) { … … 490 475 fireTableDataChanged(); 491 476 } 492 493 477 478 494 479 public DefaultComboBoxModel getAppliedPresetsModel() { 495 480 return appliedPresets; … … 497 482 498 483 public void removeAppliedPreset(Item item) { 499 if (item == null) { 500 return; 501 } 484 if (item == null) 485 return; 502 486 for (Tag tag: item.getTags()) { 503 487 if (tag.getValue() != null) { … … 521 505 } 522 506 } 523 appliedPresets.removeElement(item); 524 fireTableDataChanged(); 525 } 526 507 appliedPresets.removeElement(item); 508 fireTableDataChanged(); 509 } 510 527 511 public void clearAppliedPresets() { 528 512 appliedPresets.removeAllElements(); 529 513 fireTableDataChanged(); 530 514 } 531 515 532 516 public void highlightCurrentPreset() { 533 517 fireTableDataChanged(); 534 518 } 535 536 537 /** 538 * updates the name of a tag and sets the dirty state to true if 539 * the new name is different from the old name. 540 * 541 * @param tag the tag 542 * @param newName the new name 519 520 521 /** 522 * updates the name of a tag and sets the dirty state to true if 523 * the new name is different from the old name. 524 * 525 * @param tag the tag 526 * @param newName the new name 543 527 */ 544 528 public void updateTagName(TagModel tag, String newName) { … … 549 533 } 550 534 } 551 535 552 536 /** 553 537 * updates the value value of a tag and sets the dirty state to true if the 554 * new name is different from the old name 555 * 556 * @param tag the tag 557 * @param newValue the new value 538 * new name is different from the old name 539 * 540 * @param tag the tag 541 * @param newValue the new value 558 542 */ 559 543 public void updateTagValue(TagModel tag, String newValue) { -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagTable.java
r14520 r15319 34 34 35 35 /** 36 * This is the tabular editor component for OSM tags. 36 * This is the tabular editor component for OSM tags. 37 37 * 38 38 * … … 42 42 @SuppressWarnings("serial") 43 43 public class TagTable extends JTable { 44 44 45 45 private static Logger logger = Logger.getLogger(TagTable.class.getName()); 46 47 48 46 47 48 49 49 /** the table cell editor used by this table */ 50 50 private TableCellEditor editor = null; 51 52 53 54 /** 55 * The table has three columns. In the first column, we display error and 51 52 53 54 /** 55 * The table has three columns. In the first column, we display error and 56 56 * warning indications. The second column is used for editing rendering and 57 * editing tag keys, the third for rendering and editing tag values. 57 * editing tag keys, the third for rendering and editing tag values. 58 58 * 59 59 * @author gubaer … … 61 61 */ 62 62 static class TagTableColumnModel extends DefaultTableColumnModel { 63 63 64 64 public TagTableColumnModel() { 65 65 TableColumn col = null; 66 66 TableCellRenderer renderer = new TableCellRenderer(); 67 68 67 68 69 69 // column 0 - tag key 70 70 col = new TableColumn(0); … … 73 73 col.setCellRenderer(renderer); 74 74 addColumn(col); 75 75 76 76 // column 1 - tag value 77 77 col = new TableColumn(1); … … 80 80 col.setCellRenderer(renderer); 81 81 addColumn(col); 82 83 } 84 } 85 86 82 83 } 84 } 85 86 87 87 /** 88 88 * Action to be run when the user navigates to the next cell in the table, … … 91 91 * <ul> 92 92 * <li>it jumps over cells in the first column</li> 93 * <li>it automatically add a new empty row when the user leaves the 93 * <li>it automatically add a new empty row when the user leaves the 94 94 * last cell in the table</li> 95 95 * <ul> … … 99 99 */ 100 100 class SelectNextColumnCellAction extends AbstractAction { 101 @Overridepublic void actionPerformed(ActionEvent e) {101 public void actionPerformed(ActionEvent e) { 102 102 run(); 103 104 103 } 104 105 105 public void run() { 106 106 int col = getSelectedColumn(); 107 107 int row = getSelectedRow(); 108 108 if (getCellEditor() != null) { 109 getCellEditor().stopCellEditing(); 110 } 111 109 getCellEditor().stopCellEditing(); 110 } 111 112 112 if (col == 0) { 113 113 col++; … … 123 123 row++; 124 124 } 125 changeSelection(row, col, false, false); 126 127 } 128 } 129 130 125 changeSelection(row, col, false, false); 126 127 } 128 } 129 130 131 131 /** 132 132 * Action to be run when the user navigates to the previous cell in the table, … … 138 138 class SelectPreviousColumnCellAction extends AbstractAction { 139 139 140 @Overridepublic void actionPerformed(ActionEvent e) {140 public void actionPerformed(ActionEvent e) { 141 141 142 142 int col = getSelectedColumn(); 143 143 int row = getSelectedRow(); 144 144 if (getCellEditor() != null) { 145 getCellEditor().stopCellEditing(); 146 } 147 148 145 getCellEditor().stopCellEditing(); 146 } 147 148 149 149 if (col == 0 && row == 0) { 150 150 // change nothing … … 155 155 row--; 156 156 } 157 changeSelection(row, col, false, false); 158 159 } 160 157 changeSelection(row, col, false, false); 158 } 159 } 160 161 161 /** 162 162 * Action to be run when the user invokes a delete action on the table, for … … 169 169 * the selected tags are set to the empty string. 170 170 * 171 * If the current selection consists of cell in the third column only, the values of the 171 * If the current selection consists of cell in the third column only, the values of the 172 172 * selected tags are set to the empty string. 173 173 * 174 * If the current selection consists of cells in the second and the third column, 174 * If the current selection consists of cells in the second and the third column, 175 175 * the selected tags are removed from the model. 176 * 176 * 177 177 * This action listens to the table selection. It becomes enabled when the selection 178 * is non-empty, otherwise it is disabled. 179 * 180 * @author guaber 178 * is non-empty, otherwise it is disabled. 179 * 181 180 * 182 181 */ … … 184 183 185 184 /** 186 * delete a selection of tag names 185 * delete a selection of tag names 187 186 */ 188 187 protected void deleteTagNames() { … … 191 190 model.deleteTagNames(rows); 192 191 } 193 192 194 193 /** 195 * delete a selection of tag values 194 * delete a selection of tag values 196 195 */ 197 196 protected void deleteTagValues() { 198 197 int[] rows = getSelectedRows(); 199 198 TagEditorModel model = (TagEditorModel)getModel(); 200 model.deleteTagValues(rows); 201 } 202 199 model.deleteTagValues(rows); 200 } 201 203 202 /** 204 * delete a selection of tags 203 * delete a selection of tags 205 204 */ 206 205 protected void deleteTags() { 207 206 int[] rows = getSelectedRows(); 208 207 TagEditorModel model = (TagEditorModel)getModel(); 209 model.deleteTags(rows); 210 } 211 208 model.deleteTags(rows); 209 } 210 212 211 /** 213 * constructor 212 * constructor 214 213 */ 215 214 public DeleteAction() { … … 218 217 getColumnModel().getSelectionModel().addListSelectionListener(this); 219 218 } 220 221 222 219 220 221 222 @Override 223 223 public void run() { 224 if (!isEnabled()) {224 if (!isEnabled()) 225 225 return; 226 }227 226 getCellEditor().stopCellEditing(); 228 227 if (getSelectedColumnCount() == 1) { … … 231 230 } else if (getSelectedColumn() == 1) { 232 231 deleteTagValues(); 233 } else {232 } else 234 233 // should not happen 235 234 // 236 throw new IllegalStateException("unexpected selected clolumn: getSelectedColumn() is " + getSelectedColumn()); 237 } 235 throw new IllegalStateException("unexpected selected clolumn: getSelectedColumn() is " + getSelectedColumn()); 238 236 } else if (getSelectedColumnCount() == 2) { 239 237 deleteTags(); … … 242 240 if (model.getRowCount() == 0) { 243 241 model.ensureOneTag(); 244 requestFocusInCell(0, 0); 242 requestFocusInCell(0, 0); 245 243 } 246 244 } 247 245 248 246 /** 249 * listens to the table selection model 247 * listens to the table selection model 250 248 */ 251 @Overridepublic void valueChanged(ListSelectionEvent e) {249 public void valueChanged(ListSelectionEvent e) { 252 250 if (isEditing() && getSelectedColumnCount() == 1 && getSelectedRowCount() == 1) { 253 251 setEnabled(false); … … 258 256 } else { 259 257 setEnabled(false); 260 } 261 262 263 } 264 258 } 259 260 } 261 } 262 265 263 /** 266 264 * Action to be run when the user adds a new tag. … … 269 267 */ 270 268 class AddAction extends RunnableAction { 271 269 272 270 public AddAction() { 273 271 putValue(Action.NAME, tr("Add")); 274 272 } 275 273 274 @Override 276 275 public void run() { 277 getCellEditor().stopCellEditing(); 276 getCellEditor().stopCellEditing(); 278 277 ((TagEditorModel)getModel()).appendNewTag(); 279 278 final int rowIdx = getModel().getRowCount()-1; 280 requestFocusInCell(rowIdx, 0); 281 } 282 } 283 279 requestFocusInCell(rowIdx, 0); 280 } 281 } 282 284 283 285 284 /** the delete action */ 286 285 private RunnableAction deleteAction = null; 287 286 288 287 /** the add action */ 289 288 private RunnableAction addAction = null; 290 291 /** 292 * 293 * @return the delete action used by this table 289 290 /** 291 * 292 * @return the delete action used by this table 294 293 */ 295 294 public RunnableAction getDeleteAction() { 296 295 return deleteAction; 297 296 } 298 297 299 298 public RunnableAction getAddAction() { 300 299 return addAction; 301 300 } 302 301 303 304 /** 305 * initialize the table 302 303 /** 304 * initialize the table 306 305 */ 307 306 protected void init() { 308 309 310 setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 307 308 309 setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 311 310 setCellSelectionEnabled(true); 312 311 setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); 313 314 315 312 313 314 316 315 // make ENTER behave like TAB 317 316 // 318 317 getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) 319 318 .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "selectNextColumnCell"); 320 319 321 320 // install custom navigation actions … … 328 327 // 329 328 deleteAction = new DeleteAction(); 330 329 331 330 // create the add action 332 331 // 333 332 addAction = new AddAction(); 334 333 getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) 335 334 .put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, KeyEvent.CTRL_MASK), "addTag"); 336 335 getActionMap().put("addTag", addAction); 337 338 336 337 339 338 // create the table cell editor and set it to key and value columns 340 339 // … … 343 342 getColumnModel().getColumn(0).setCellEditor(editor); 344 343 getColumnModel().getColumn(1).setCellEditor(editor); 345 346 } 347 348 /** 349 * constructor 344 345 } 346 347 /** 348 * constructor 350 349 * 351 350 * @param model 352 351 * @param columnModel 353 352 */ 354 public TagTable(TableModel model) { 353 public TagTable(TableModel model) { 355 354 super(model, new TagTableColumnModel()); 356 355 init(); 357 356 } 358 359 360 357 358 359 361 360 /** 362 361 * adjusts the width of the columns for the tag name and the tag value … … 375 374 tcm.getColumn(0).setMaxWidth(width); 376 375 tcm.getColumn(1).setMinWidth(width); 377 tcm.getColumn(1).setMaxWidth(width); 378 } 379 } 380 381 376 tcm.getColumn(1).setMaxWidth(width); 377 } 378 } 379 380 382 381 @Override protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, 383 384 382 int condition, boolean pressed) { 383 385 384 // handle delete key 386 385 // 387 388 389 }390 391 392 393 394 /** 395 * @param autoCompletionList 386 if (e.getKeyCode() == KeyEvent.VK_DELETE) { 387 getDeleteAction().run(); 388 } 389 return super.processKeyBinding(ks, e, condition, pressed); 390 } 391 392 393 /** 394 * @param autoCompletionList 396 395 */ 397 396 public void setAutoCompletionList(AutoCompletionList autoCompletionList) { 398 if (autoCompletionList == null) { 399 return; 400 } 397 if (autoCompletionList == null) 398 return; 401 399 if (editor != null) { 402 400 editor.setAutoCompletionList(autoCompletionList); 403 } 404 } 405 401 } 402 } 403 406 404 public void setAutoCompletionCache(AutoCompletionCache acCache) { 407 405 if (acCache == null) { 408 406 logger.warning("argument acCache should not be null. Aborting."); 409 return; 407 return; 410 408 } 411 409 if (editor != null) { … … 413 411 } 414 412 } 415 413 416 414 public AutoCompletionList getAutoCompletionList() { 417 if (editor != null) {415 if (editor != null) 418 416 return editor.getAutoCompletionList(); 419 } else {417 else 420 418 return null; 421 } 422 } 423 424 419 } 420 421 425 422 public TableCellEditor getTableCellEditor() { 426 423 return editor; … … 435 432 editor.getEditor().addKeyListener(l); 436 433 } 437 438 434 435 439 436 public void requestFocusInCell(final int row, final int col) { 440 437 441 438 // the following code doesn't work reliably. If a table cell 442 // gains focus using editCellAt() and requestFocusInWindow() 439 // gains focus using editCellAt() and requestFocusInWindow() 443 440 // it isn't possible to tab to the next table cell using TAB or 444 441 // ENTER. Don't know why. 445 // 442 // 446 443 // tblTagEditor.editCellAt(row, col); 447 444 // if (tblTagEditor.getEditorComponent() != null) { … … 451 448 // this is a workaround. We move the focus to the respective cell 452 449 // using a simulated mouse click. In this case one can tab out of 453 // the cell using TAB and ENTER. 454 // 450 // the cell using TAB and ENTER. 451 // 455 452 Rectangle r = getCellRect(row,col, false); 456 453 Point p = new Point(r.x + r.width/2, r.y + r.height/2); 457 454 SwingUtilities.convertPointToScreen(p, this); 458 455 // logger.info("simulating mouse click event at point " + p.toString()); 459 456 460 457 try { 461 458 Robot robot = new Robot(); … … 465 462 } catch(AWTException e) { 466 463 logger.log(Level.SEVERE, "failed to simulate mouse click event at (" + r.x + "," + r.y + "). Exception: " + e.toString()); 467 return; 468 } 469 470 } 471 472 464 return; 465 } 466 467 } 468 469 473 470 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/ui/NameIconCellRenderer.java
r14328 r15319 15 15 16 16 public class NameIconCellRenderer extends JLabel implements TableCellRenderer { 17 17 18 18 private static Logger logger = Logger.getLogger(NameIconCellRenderer.class.getName()); 19 19 public static final Color BG_COLOR_SELECTED = new Color(143,170,255); 20 20 21 21 22 22 protected void init() { … … 24 24 setFont(new Font("SansSerif",Font.PLAIN,10)); 25 25 } 26 26 27 27 public NameIconCellRenderer() { 28 28 init(); 29 29 } 30 31 @Override 30 32 31 public Component getTableCellRendererComponent(JTable table, Object value, 33 32 boolean isSelected, boolean hasFocus, int rowIndex, int colIndex) { 34 33 35 34 if (isSelected) { 36 setBackground(BG_COLOR_SELECTED); 35 setBackground(BG_COLOR_SELECTED); 37 36 } else { 38 37 setBackground(Color.WHITE); … … 41 40 setText(provider.getName()); 42 41 setIcon(provider.getIcon()); 43 return this; 42 return this; 44 43 } 45 44 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/ui/PresetsTableModel.java
r14328 r15319 15 15 16 16 private static final Logger logger = Logger.getLogger(PresetsTableModel.class.getName()); 17 18 privateArrayList<TableModelListener> listeners = new ArrayList<TableModelListener>();19 privateArrayList<Item> items = new ArrayList<Item>();20 privateArrayList<Item> visibleItems = new ArrayList<Item>();21 22 23 24 17 18 private final ArrayList<TableModelListener> listeners = new ArrayList<TableModelListener>(); 19 private final ArrayList<Item> items = new ArrayList<Item>(); 20 private final ArrayList<Item> visibleItems = new ArrayList<Item>(); 21 private Presets presets = null; 22 23 24 protected void initModelFromPresets(Presets presets) { 25 25 for(Group group: presets.getGroups()) { 26 26 for(Item item: group.getItems()) { … … 29 29 } 30 30 } 31 32 33 34 35 36 37 38 39 40 41 31 } 32 33 34 public PresetsTableModel() { 35 } 36 37 public PresetsTableModel(Presets presets) { 38 setPresets(presets); 39 } 40 41 42 42 public Presets getPresets() { 43 43 return presets; … … 57 57 public void addTableModelListener(TableModelListener l) { 58 58 synchronized(listeners) { 59 if (l == null) {59 if (l == null) 60 60 return; 61 }62 61 if (!listeners.contains(l)) { 63 62 listeners.add(l); … … 71 70 } 72 71 73 @Override74 72 public int getColumnCount() { 75 73 return 2; 76 74 } 77 75 78 79 @Override80 76 public int getRowCount() { 81 77 return visibleItems.size(); 82 78 } 83 79 84 @Override85 80 public Object getValueAt(int rowIndex, int columnIndex) { 86 81 Item item = visibleItems.get(rowIndex); 87 82 switch(columnIndex) { 88 89 90 default: return "unknown";91 83 case 0: return item.getParent(); 84 case 1: return item; 85 default: return "unknown"; 86 92 87 } 93 88 } … … 104 99 listeners.remove(l); 105 100 } 106 } 101 } 107 102 } 108 103 109 104 @Override 110 105 public void setValueAt(Object value, int rowIndex, int columnIndex) { 111 // do nothing. No editing allowed 106 // do nothing. No editing allowed 112 107 } 113 108 114 115 109 public Item getVisibleItem(int idx) { 116 if (idx < 0 || idx >= this.visibleItems.size()) {110 if (idx < 0 || idx >= this.visibleItems.size()) 117 111 throw new IndexOutOfBoundsException("index out of bounds. idx=" + idx); 118 }119 112 return visibleItems.get(idx); 120 113 } 121 122 123 114 124 115 public void filter(String filter) { 125 116 synchronized(this) { … … 129 120 visibleItems.add(item); 130 121 } 131 } else { 122 } else { 132 123 visibleItems.clear(); 133 124 filter = filter.toLowerCase(); 134 125 for(Item item: items) { 135 126 if ( (item.getName() != null && item.getName().toLowerCase().trim().startsWith(filter)) 136 127 || (item.getParent().getName() != null && item.getParent().getName().toLowerCase().trim().startsWith(filter))) { 137 128 visibleItems.add(item); 138 129 } 139 } 130 } 140 131 } 141 132 fireTableDataChanged(); 142 133 fireTableStructureChanged(); 143 134 } 144 135 145 136 } 146 137 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/ui/TabularPresetSelector.java
r14328 r15319 39 39 private PresetsTable presetsTable = null; 40 40 private JTextField tfFilter = null; 41 private ArrayList<IPresetSelectorListener> listeners = new ArrayList<IPresetSelectorListener>();41 private final ArrayList<IPresetSelectorListener> listeners = new ArrayList<IPresetSelectorListener>(); 42 42 private JScrollPane scrollPane; 43 43 private JButton btnApply; 44 45 44 45 46 46 protected JPanel buildFilterPanel() { 47 47 JPanel pnl = new JPanel(); … … 54 54 pnl.add(btn); 55 55 btn.addActionListener( 56 new ActionListener() { 57 @Override 58 public void actionPerformed(ActionEvent e) { 59 filter(tfFilter.getText()); 60 } 61 62 } 56 new ActionListener() { 57 public void actionPerformed(ActionEvent e) { 58 filter(tfFilter.getText()); 59 } 60 61 } 63 62 ); 64 63 btn = new JButton(tr("Clear")); … … 66 65 btn.addActionListener( 67 66 new ActionListener() { 68 @Override69 67 public void actionPerformed(ActionEvent e) { 70 68 tfFilter.setText(""); 71 69 tfFilter.requestFocus(); 72 } 73 } 74 );70 } 71 } 72 ); 75 73 return pnl; 76 74 } 77 78 79 75 76 77 80 78 protected JScrollPane buildPresetGrid() { 81 79 82 80 presetsTable = new PresetsTable(new PresetsTableModel(),new PresetsTableColumnModel()); 83 81 84 82 scrollPane = new JScrollPane(presetsTable); 85 83 86 84 scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); 87 85 scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 88 86 89 87 // this adapters ensures that the width of the tag table columns is adjusted 90 // to the width of the scroll pane viewport. Also tried to overwrite 88 // to the width of the scroll pane viewport. Also tried to overwrite 91 89 // getPreferredViewportSize() in JTable, but did not work. 92 90 // … … 94 92 new ComponentAdapter() { 95 93 @Override public void componentResized(ComponentEvent e) { 96 97 98 99 100 } 101 ); 102 103 // add the double click listener 94 super.componentResized(e); 95 Dimension d = scrollPane.getViewport().getExtentSize(); 96 presetsTable.adjustColumnWidth(d.width); 97 } 98 } 99 ); 100 101 // add the double click listener 104 102 // 105 103 presetsTable.addMouseListener(new DoubleClickAdapter()); 106 104 107 105 // replace Enter action. apply the current preset on enter 108 106 // … … 117 115 } 118 116 }; 119 117 120 118 presetsTable.registerKeyboardAction( 121 enterAction,122 "Enter",123 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),124 JComponent.WHEN_FOCUSED125 ); 126 119 enterAction, 120 "Enter", 121 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), 122 JComponent.WHEN_FOCUSED 123 ); 124 127 125 return scrollPane; 128 126 } 129 127 130 128 protected JPanel buildControlButtonPanel() { 131 129 JPanel pnl = new JPanel(); … … 134 132 pnl.add(btnApply); 135 133 btnApply.addActionListener( 136 new ActionListener() { 137 @Override 138 public void actionPerformed(ActionEvent arg0) { 139 int row = presetsTable.getSelectedRow(); 140 if (row >=0) { 141 Item item = getModel().getVisibleItem(row); 142 fireItemSelected(item); 143 } 144 } 145 } 146 ); 147 return pnl; 148 } 149 134 new ActionListener() { 135 public void actionPerformed(ActionEvent arg0) { 136 int row = presetsTable.getSelectedRow(); 137 if (row >=0) { 138 Item item = getModel().getVisibleItem(row); 139 fireItemSelected(item); 140 } 141 } 142 } 143 ); 144 return pnl; 145 } 146 150 147 protected void build() { 151 148 setLayout(new BorderLayout()); … … 153 150 add(buildPresetGrid(), BorderLayout.CENTER); 154 151 add(buildControlButtonPanel(), BorderLayout.SOUTH); 155 152 156 153 // wire the text field for filter expressions to the prests 157 154 // table … … 159 156 tfFilter.getDocument().addDocumentListener( 160 157 new DocumentListener() { 161 @Override162 158 public void changedUpdate(DocumentEvent arg0) { 163 159 onUpdate(); 164 160 } 165 161 166 @Override167 162 public void insertUpdate(DocumentEvent arg0) { 168 163 onUpdate(); 169 164 } 170 165 171 @Override172 166 public void removeUpdate(DocumentEvent arg0) { 173 167 onUpdate(); 174 168 } 175 169 176 170 protected void onUpdate() { 177 178 } 179 } 180 181 171 filter(tfFilter.getText()); 172 } 173 } 174 ); 175 182 176 tfFilter.addActionListener( 183 177 new ActionListener() { 184 @Override185 178 public void actionPerformed(ActionEvent e) { 186 179 filter(tfFilter.getText()); 187 } 188 } 189 ); 190 180 } 181 } 182 ); 183 191 184 // wire the apply button to the selection model of the preset table 192 // 185 // 193 186 presetsTable.getSelectionModel().addListSelectionListener( 194 new ListSelectionListener() { 195 196 @Override 197 public void valueChanged(ListSelectionEvent e) { 198 btnApply.setEnabled(presetsTable.getSelectedRowCount() != 0); 199 } 200 } 201 ); 202 203 187 new ListSelectionListener() { 188 public void valueChanged(ListSelectionEvent e) { 189 btnApply.setEnabled(presetsTable.getSelectedRowCount() != 0); 190 } 191 } 192 ); 193 194 204 195 // load the set of presets and bind them to the preset table 205 196 // … … 208 199 presetsTable.getSelectionModel().clearSelection(); 209 200 btnApply.setEnabled(false); 210 211 } 212 201 202 } 203 213 204 public void bindTo(Presets presets) { 214 205 PresetsTableModel model = (PresetsTableModel)presetsTable.getModel(); 215 206 model.setPresets(presets); 216 207 } 217 208 218 209 public TabularPresetSelector() { 219 210 build(); … … 227 218 } 228 219 } 229 220 230 221 public void removePresetSelectorListener(IPresetSelectorListener listener) { 231 222 synchronized(this.listeners) { … … 235 226 } 236 227 } 237 228 238 229 protected void fireItemSelected(Item item) { 239 230 synchronized(this.listeners) { … … 243 234 } 244 235 } 245 246 247 248 236 237 238 239 249 240 private class DoubleClickAdapter extends MouseAdapter { 250 241 @Override … … 257 248 } 258 249 } 259 260 250 251 261 252 public void filter(String filter) { 262 253 presetsTable.getSelectionModel().clearSelection(); 263 254 getModel().filter(filter); 264 255 265 256 presetsTable.scrollRectToVisible(presetsTable.getCellRect(0, 0, false)); 266 257 267 258 // we change the number of rows by applying a filter condition. Because 268 259 // the table is embedded in a JScrollPane which again may be embedded in 269 // other JScrollPanes or JSplitPanes it seems that we have to recalculate 260 // other JScrollPanes or JSplitPanes it seems that we have to recalculate 270 261 // the layout and repaint the component tree. Maybe there is a more efficient way 271 262 // to keep the GUI in sync with the number of rows in table. By trial 272 // and error I ended up with the following lines. 273 // 263 // and error I ended up with the following lines. 264 // 274 265 Component c = presetsTable; 275 266 while(c != null) { … … 279 270 } 280 271 } 281 282 272 273 283 274 protected PresetsTableModel getModel() { 284 275 return (PresetsTableModel)presetsTable.getModel(); 285 276 } 286 277 287 278 public void installKeyAction(Action a) { 288 279 getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)a.getValue(AbstractAction.ACCELERATOR_KEY), a.getValue(AbstractAction.NAME)); … … 290 281 291 282 } 292 283 293 284 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/TagSpecifications.java
r14329 r15319 7 7 import java.io.Reader; 8 8 import java.util.ArrayList; 9 import java.util.Collections;10 9 import java.util.List; 11 import java.util.Map;12 10 import java.util.logging.Level; 13 11 import java.util.logging.Logger; … … 36 34 */ 37 35 public class TagSpecifications { 38 36 39 37 final static public String ATTR_KEY = "key"; 40 38 final static public String ATTR_TYPE = "type"; … … 47 45 final static public String ELEM_TAG = "tag"; 48 46 final static public String ELEM_LABEL = "label"; 49 47 50 48 final static public String DTD = "osm-tag-definitions.dtd"; 51 52 53 /** the default name of the resource file with the tag specifications */ 49 50 51 /** the default name of the resource file with the tag specifications */ 54 52 static public final String RES_NAME_TAG_SPECIFICATIONS = "/resources/osm-tag-definitions.xml"; 55 53 56 54 /** the logger object */ 57 55 private static Logger logger = Logger.getLogger(TagSpecification.class.getName()); 58 56 59 57 /** list of tag specifications managed list */ 60 58 private ArrayList<TagSpecification> tagSpecifications = null; 61 62 63 59 60 61 64 62 private static TagSpecifications instance = null; 65 63 66 64 /** 67 65 * loads the the tag specifications from the resource file given by 68 * {@link #RES_NAME_TAG_SPECIFICATIONS}. 66 * {@link #RES_NAME_TAG_SPECIFICATIONS}. 69 67 * 70 68 * @return the list of {@link TagSpecification}s … … 81 79 reader.close(); 82 80 instance = spec; 83 84 } 85 81 82 } 83 86 84 static public TagSpecifications getInstance() throws Exception { 87 85 if (instance == null) { … … 90 88 return instance; 91 89 } 92 93 /** 94 * constructor 90 91 /** 92 * constructor 95 93 */ 96 94 public TagSpecifications() { 97 95 tagSpecifications = new ArrayList<TagSpecification>(); 98 96 } 99 100 101 /** 102 * loads the tag specifications from a specific reader 97 98 99 /** 100 * loads the tag specifications from a specific reader 103 101 * 104 * @param in the reader to read from 105 * @throws Exception thrown, if an exception occurs 102 * @param in the reader to read from 103 * @throws Exception thrown, if an exception occurs 106 104 */ 107 105 public void load(Reader in) throws Exception { 108 106 XMLReader parser; 109 107 110 108 try { 111 109 parser = XMLReaderFactory.createXMLReader(); … … 117 115 parser.setFeature("http://xml.org/sax/features/namespaces", true); 118 116 parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true); 119 120 117 parser.parse(new InputSource(in)); 118 121 119 } catch (Exception e) { 122 120 logger.log(Level.SEVERE, "failed to load tag specificatoin file", e); … … 125 123 parser = null; 126 124 } 127 128 129 125 126 127 130 128 } 131 129 … … 143 141 return keys; 144 142 } 145 143 146 144 public List<AutoCompletionListItem> getLabelsForAutoCompletion(String forKey, AutoCompletionContext context) { 147 145 ArrayList<AutoCompletionListItem> items = new ArrayList<AutoCompletionListItem>(); … … 162 160 return items; 163 161 } 164 165 162 163 166 164 /** 167 165 * replies a list of {@see KeyValuePair}s for all {@see TagSpecification}s and 168 166 * {@see LableSpecification}s. 169 167 * 170 * @return the list 168 * @return the list 171 169 */ 172 170 public ArrayList<KeyValuePair> asList() { 173 171 ArrayList<KeyValuePair> entries = new ArrayList<KeyValuePair>(); 174 172 175 173 for (TagSpecification s : tagSpecifications) { 176 174 for (LableSpecification l : s.getLables()) { … … 178 176 } 179 177 } 180 return entries; 181 } 182 183 184 185 /** 186 * The SAX handler for reading XML files with tag specifications 178 return entries; 179 } 180 181 182 183 /** 184 * The SAX handler for reading XML files with tag specifications 187 185 * 188 * @author gubaer 186 * @author gubaer 189 187 * 190 188 */ 191 189 class Handler extends DefaultHandler { 192 190 193 191 /** the current tag specification. Not null, while parsing the content 194 192 * between <tag> ... </tag> 195 193 */ 196 194 private TagSpecification currentTagSpecification = null; 197 198 195 196 199 197 @Override 200 198 public void endDocument() throws SAXException { … … 202 200 } 203 201 204 202 205 203 206 204 @Override … … 223 221 * parses a string value consisting of 'yes' or 'no' (exactly, case 224 222 * sensitive) 225 * 223 * 226 224 * @param value the string value 227 225 * @return true, if value is <code>yes</code>; false, if value is <code>no</code> … … 229 227 */ 230 228 protected boolean parseYesNo(String value) throws SAXException { 231 if ("yes".equals(value)) {229 if ("yes".equals(value)) 232 230 return true; 233 } else if ("no".equals(value)) {234 return false; 235 } else {231 else if ("no".equals(value)) 232 return false; 233 else 236 234 throw new SAXException("expected 'yes' or 'no' as attribute value, got '" + value + "'"); 237 } 238 } 239 235 } 236 240 237 /** 241 238 * handles a start element with name <code>osm-tag-definitions</code> 242 239 * 243 * @param atts the XML attributes 244 * @throws SAXException 240 * @param atts the XML attributes 241 * @throws SAXException 245 242 */ 246 243 protected void startElementOsmTagDefinitions(Attributes atts) throws SAXException { 247 244 tagSpecifications = new ArrayList<TagSpecification>(); 248 245 } 249 246 250 247 /** 251 248 * handles an end element with name <code>osm-tag-specifications</code> … … 256 253 // do nothing 257 254 } 258 259 /** 260 * handles a start element with name <code>tag</code> 261 * 262 * @param atts the XML attributes of the element 255 256 /** 257 * handles a start element with name <code>tag</code> 258 * 259 * @param atts the XML attributes of the element 263 260 * @throws SAXException 264 261 */ … … 268 265 String name = atts.getQName(i); 269 266 String value = atts.getValue(i); 270 267 271 268 if (ATTR_KEY.equals(name)) { 272 269 currentTagSpecification.setKey(value); 273 } else if (ATTR_TYPE.equals(name)) { 270 } else if (ATTR_TYPE.equals(name)) { 274 271 currentTagSpecification.setType(value); 275 272 } else if (ATTR_FOR_NODE.equals(name)) { … … 279 276 } else if (ATTR_FOR_RELATION.equals(name)) { 280 277 currentTagSpecification.setApplicableToRelation(parseYesNo(value)); 281 } else {278 } else 282 279 throw new SAXException("unknown attribut '" + name + "' on element 'tag'"); 283 } 284 } 285 } 286 287 288 /** 289 * handles an end element with name <code>tag</code> 280 } 281 } 282 283 284 /** 285 * handles an end element with name <code>tag</code> 290 286 * @throws SAXException 291 287 */ … … 293 289 tagSpecifications.add(currentTagSpecification); 294 290 currentTagSpecification = null; 295 296 } 297 298 299 /** 300 * handles a start element with name <code>label</code> 301 * 302 * @param atts the XML attributes 291 292 } 293 294 295 /** 296 * handles a start element with name <code>label</code> 297 * 298 * @param atts the XML attributes 303 299 * @throws SAXException 304 300 */ 305 301 protected void startElementLabel(Attributes atts) throws SAXException { 306 LableSpecification ls = new LableSpecification(); 302 LableSpecification ls = new LableSpecification(); 307 303 for (int i=0; i< atts.getLength(); i++) { 308 304 String name = atts.getQName(i); 309 305 String value = atts.getValue(i); 310 306 311 307 if (ATTR_VALUE.equals(name)) { 312 308 ls.setValue(value); … … 317 313 } else if (ATTR_FOR_RELATION.equals(name)) { 318 314 ls.setApplicableToRelation(parseYesNo(value)); 319 } else {315 } else 320 316 throw new SAXException("unknown attribut '" + name + "' on element 'lable'"); 321 }322 317 } 323 318 currentTagSpecification.addLable(ls); 324 319 } 325 320 326 321 /** 327 322 * handles an end element with name <code>label</code> … … 330 325 */ 331 326 protected void endElementLabel() throws SAXException { 332 // do nothing 333 } 334 327 // do nothing 328 } 329 335 330 @Override 336 331 public void startElement(String namespaceURI, String localName, String qName, … … 342 337 } else if (ELEM_LABEL.equals(qName)) { 343 338 startElementLabel(atts); 344 } else {339 } else 345 340 throw new SAXException("unknown element '" + qName + "'"); 346 } 347 } 348 341 } 342 349 343 @Override 350 344 public void endElement(String namespaceURI, String localName, String qName) 351 345 throws SAXException { 352 346 if (ELEM_ROOT.equals(qName)) { 353 347 endElementOsmTagDefinitions(); … … 356 350 } else if (ELEM_LABEL.equals(qName)) { 357 351 endElementLabel(); 358 } else {352 } else 359 353 throw new SAXException("unknown element '" + qName + "'"); 360 }361 354 } 362 355 … … 366 359 logger.log(Level.WARNING, "XML parsing warning", e); 367 360 } 368 369 370 371 } 372 373 361 362 363 364 } 365 366 374 367 /** 375 368 * … … 378 371 class ResourceEntityResolver implements EntityResolver { 379 372 380 @Override381 373 public InputSource resolveEntity(String publicId, String systemId) 382 383 if (systemId != null && systemId.endsWith(DTD)) {374 throws SAXException, IOException { 375 if (systemId != null && systemId.endsWith(DTD)) 384 376 return new InputSource( 385 377 TagSpecifications.class.getResourceAsStream(DTD) 386 378 ); 387 } else {379 else 388 380 throw new SAXException("couldn't load external DTD '" + systemId + "'"); 389 } 390 } 391 392 } 393 394 381 } 382 383 } 384 385 395 386 static public void main(String args[]) throws Exception{ 396 387 TagSpecifications.loadFromResources(); 397 388 } 398 389 399 390 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/KeyValueCellRenderer.java
r14330 r15319 11 11 12 12 public class KeyValueCellRenderer extends JLabel implements TableCellRenderer { 13 13 14 14 private static Logger logger = Logger.getLogger(KeyValueCellRenderer.class.getName()); 15 15 public static final Color BG_COLOR_SELECTED = new Color(143,170,255); 16 16 17 17 18 18 protected void init() { … … 20 20 setOpaque(true); 21 21 } 22 22 23 23 public KeyValueCellRenderer() { 24 24 init(); 25 25 } 26 27 @Override 26 28 27 public Component getTableCellRendererComponent(JTable table, Object value, 29 28 boolean isSelected, boolean hasFocus, int rowIndex, int colIndex) { 30 29 31 30 if (isSelected) { 32 setBackground(BG_COLOR_SELECTED); 31 setBackground(BG_COLOR_SELECTED); 33 32 } else { 34 33 setBackground(Color.WHITE); … … 36 35 setText((String)value); 37 36 setIcon(null); 38 return this; 37 return this; 39 38 } 40 39 } -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TabularTagSelector.java
r14330 r15319 35 35 public class TabularTagSelector extends JPanel { 36 36 37 private TagsTable tagsTable; 37 private TagsTable tagsTable; 38 38 private JTextField tfFilter; 39 39 private JButton btnApply; 40 40 private JScrollPane scrollPane; 41 private ArrayList<ITagSelectorListener> listeners = new ArrayList<ITagSelectorListener>();42 43 41 private final ArrayList<ITagSelectorListener> listeners = new ArrayList<ITagSelectorListener>(); 42 43 44 44 protected JPanel buildFilterPanel() { 45 45 JPanel pnl = new JPanel(); … … 52 52 pnl.add(btn); 53 53 btn.addActionListener( 54 new ActionListener() { 55 @Override 56 public void actionPerformed(ActionEvent e) { 57 filter(tfFilter.getText()); 58 } 59 60 } 54 new ActionListener() { 55 public void actionPerformed(ActionEvent e) { 56 filter(tfFilter.getText()); 57 } 58 59 } 61 60 ); 62 61 btn = new JButton(tr("Clear")); … … 64 63 btn.addActionListener( 65 64 new ActionListener() { 66 @Override67 65 public void actionPerformed(ActionEvent e) { 68 66 tfFilter.setText(""); 69 67 tfFilter.requestFocus(); 70 } 71 } 72 );68 } 69 } 70 ); 73 71 return pnl; 74 72 } 75 73 76 74 protected JScrollPane buildPresetGrid() { 77 75 78 76 tagsTable = new TagsTable(new TagsTableModel(),new TagsTableColumnModel()); 79 77 getModel().initFromTagSpecifications(); 80 78 81 79 scrollPane = new JScrollPane(tagsTable); 82 80 83 81 scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); 84 82 scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 85 83 86 84 // this adapters ensures that the width of the tag table columns is adjusted 87 // to the width of the scroll pane viewport. Also tried to overwrite 85 // to the width of the scroll pane viewport. Also tried to overwrite 88 86 // getPreferredViewportSize() in JTable, but did not work. 89 87 // … … 91 89 new ComponentAdapter() { 92 90 @Override public void componentResized(ComponentEvent e) { 93 94 95 96 97 } 98 ); 99 100 // add the double click listener 91 super.componentResized(e); 92 Dimension d = scrollPane.getViewport().getExtentSize(); 93 tagsTable.adjustColumnWidth(d.width); 94 } 95 } 96 ); 97 98 // add the double click listener 101 99 // 102 100 tagsTable.addMouseListener(new DoubleClickAdapter()); 103 101 104 102 // replace Enter action. apply the current preset on enter 105 103 // … … 114 112 } 115 113 }; 116 114 117 115 tagsTable.registerKeyboardAction( 118 enterAction,119 "Enter",120 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),121 JComponent.WHEN_FOCUSED122 ); 123 116 enterAction, 117 "Enter", 118 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), 119 JComponent.WHEN_FOCUSED 120 ); 121 124 122 return scrollPane; 125 123 } 126 127 124 125 128 126 protected JPanel buildControlButtonPanel() { 129 127 JPanel pnl = new JPanel(); … … 132 130 pnl.add(btnApply); 133 131 btnApply.addActionListener( 134 new ActionListener() { 135 @Override 136 public void actionPerformed(ActionEvent arg0) { 137 int row = tagsTable.getSelectedRow(); 138 if (row >=0) { 139 KeyValuePair item = getModel().getVisibleItem(row); 140 fireItemSelected(item); 141 } 142 } 143 } 144 ); 145 return pnl; 146 } 147 132 new ActionListener() { 133 public void actionPerformed(ActionEvent arg0) { 134 int row = tagsTable.getSelectedRow(); 135 if (row >=0) { 136 KeyValuePair item = getModel().getVisibleItem(row); 137 fireItemSelected(item); 138 } 139 } 140 } 141 ); 142 return pnl; 143 } 144 148 145 protected void build() { 149 146 setLayout(new BorderLayout()); … … 151 148 add(buildPresetGrid(), BorderLayout.CENTER); 152 149 add(buildControlButtonPanel(), BorderLayout.SOUTH); 153 150 154 151 // wire the text field for filter expressions to the prests 155 152 // table … … 157 154 tfFilter.getDocument().addDocumentListener( 158 155 new DocumentListener() { 159 @Override160 156 public void changedUpdate(DocumentEvent arg0) { 161 157 onUpdate(); 162 158 } 163 159 164 @Override165 160 public void insertUpdate(DocumentEvent arg0) { 166 161 onUpdate(); 167 162 } 168 163 169 @Override170 164 public void removeUpdate(DocumentEvent arg0) { 171 165 onUpdate(); 172 166 } 173 167 174 168 protected void onUpdate() { 175 176 } 177 } 178 179 169 filter(tfFilter.getText()); 170 } 171 } 172 ); 173 180 174 tfFilter.addActionListener( 181 175 new ActionListener() { 182 @Override183 176 public void actionPerformed(ActionEvent e) { 184 177 filter(tfFilter.getText()); 185 } 186 } 187 ); 188 178 } 179 } 180 ); 181 189 182 // wire the apply button to the selection model of the preset table 190 // 183 // 191 184 tagsTable.getSelectionModel().addListSelectionListener( 192 new ListSelectionListener() { 193 194 @Override 195 public void valueChanged(ListSelectionEvent e) { 196 btnApply.setEnabled(tagsTable.getSelectedRowCount() != 0); 197 } 198 } 199 ); 200 201 185 new ListSelectionListener() { 186 public void valueChanged(ListSelectionEvent e) { 187 btnApply.setEnabled(tagsTable.getSelectedRowCount() != 0); 188 } 189 } 190 ); 191 192 202 193 // load the set of presets and bind them to the preset table 203 194 // 204 195 tagsTable.getSelectionModel().clearSelection(); 205 196 btnApply.setEnabled(false); 206 207 } 208 209 197 198 } 199 200 public TabularTagSelector() { 210 201 build(); 211 202 } 212 213 214 203 204 205 public void filter(String filter) { 215 206 tagsTable.getSelectionModel().clearSelection(); 216 207 getModel().filter(filter); 217 208 218 209 tagsTable.scrollRectToVisible(tagsTable.getCellRect(0, 0, false)); 219 210 220 211 // we change the number of rows by applying a filter condition. Because 221 212 // the table is embedded in a JScrollPane which again may be embedded in 222 // other JScrollPanes or JSplitPanes it seems that we have to recalculate 213 // other JScrollPanes or JSplitPanes it seems that we have to recalculate 223 214 // the layout and repaint the component tree. Maybe there is a more efficient way 224 215 // to keep the GUI in sync with the number of rows in table. By trial 225 // and error I ended up with the following lines. 226 // 216 // and error I ended up with the following lines. 217 // 227 218 Component c = tagsTable; 228 219 while(c != null) { … … 232 223 } 233 224 } 234 235 236 237 }225 226 protected TagsTableModel getModel() { 227 return (TagsTableModel)tagsTable.getModel(); 228 } 238 229 239 230 … … 245 236 } 246 237 } 247 238 248 239 public void removeTagSelectorListener(ITagSelectorListener listener) { 249 240 synchronized(this.listeners) { … … 253 244 } 254 245 } 255 246 256 247 protected void fireItemSelected(KeyValuePair pair) { 257 248 synchronized(this.listeners) { -
applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TagsTableModel.java
r14330 r15319 1 1 package org.openstreetmap.josm.plugins.tageditor.tagspec.ui; 2 import static org.openstreetmap.josm.tools.I18n.tr; 2 3 3 4 import java.util.ArrayList; … … 14 15 15 16 public class TagsTableModel extends AbstractTableModel { 16 17 17 18 static private Logger logger = Logger.getLogger(TagsTableModel.class.getName()); 18 19 19 20 private ArrayList<KeyValuePair> items = null; 20 21 private ArrayList<KeyValuePair> visibleItems = null; … … 24 25 visibleItems = new ArrayList<KeyValuePair>(); 25 26 } 26 27 27 28 protected void sort() { 28 29 Collections.sort( 29 items, 30 new Comparator<KeyValuePair>() { 30 items, 31 new Comparator<KeyValuePair>() { 32 public int compare(KeyValuePair self, 33 KeyValuePair other) { 34 int ret =self.getKey().compareToIgnoreCase(other.getKey()); 31 35 32 @Override 33 public int compare(KeyValuePair self, 34 KeyValuePair other) { 35 int ret =self.getKey().compareToIgnoreCase(other.getKey()); 36 37 if (ret == 0) { 38 return self.getValue().compareToIgnoreCase(other.getValue()); 39 } else { 40 return ret; 36 if (ret == 0) 37 return self.getValue().compareToIgnoreCase(other.getValue()); 38 else 39 return ret; 41 40 } 42 } 43 } 41 } 44 42 ); 45 43 } 46 44 47 45 protected void clear() { 48 46 items.clear(); 49 47 visibleItems.clear(); 50 48 } 51 49 52 50 public void initFromTagSpecifications() { 53 51 clear(); 54 52 TagSpecifications spec; 55 53 56 54 try { 57 55 spec = TagSpecifications.getInstance(); 58 56 } catch(Exception e) { 59 57 logger.log(Level.SEVERE, "failed to init TagTableModel. Exception:" + e); 60 return; 58 return; 61 59 } 62 60 63 61 items = spec.asList(); 64 62 sort(); … … 67 65 } 68 66 } 69 70 @Override 67 71 68 public int getColumnCount() { 72 69 return 2; 73 70 } 74 71 75 @Override76 72 public int getRowCount() { 77 73 return visibleItems.size(); 78 74 } 79 75 80 @Override81 76 public Object getValueAt(int row, int col) { 82 77 KeyValuePair pair = visibleItems.get(row); … … 86 81 default: 87 82 /* should not happen */ 88 throw new IllegalArgumentException( "unexpected column number " + col);89 } 83 throw new IllegalArgumentException(tr("unexpected column number {0}",col)); 84 } 90 85 } 91 86 92 87 public void filter(String filter) { 93 88 synchronized(this) { … … 97 92 visibleItems.add(pair); 98 93 } 99 } else { 94 } else { 100 95 visibleItems.clear(); 101 96 filter = filter.toLowerCase(); 102 97 for(KeyValuePair pair: items) { 103 98 if (pair.getKey().toLowerCase().trim().startsWith(filter) 104 99 || pair.getValue().toLowerCase().trim().startsWith(filter)) { 105 100 visibleItems.add(pair); 106 101 } 107 } 102 } 108 103 } 109 104 fireTableDataChanged(); … … 114 109 @Override 115 110 public boolean isCellEditable(int rowIndex, int columnIndex) { 116 return false; 111 return false; 117 112 } 118 113 119 114 public KeyValuePair getVisibleItem(int row) { 120 if (row < 0 || row >= visibleItems.size()) {115 if (row < 0 || row >= visibleItems.size()) 121 116 throw new IndexOutOfBoundsException("row is out of bound: row=" + row); 122 }123 117 return visibleItems.get(row); 124 118 }
Note:
See TracChangeset
for help on using the changeset viewer.