Changeset 2974 in josm for trunk/src/org/openstreetmap/josm/gui/tagging/TagTable.java
- Timestamp:
- 13.02.2010 17:45:10 (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/tagging/TagTable.java
r2626 r2974 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.applet.Applet; 6 7 import java.awt.AWTException; 8 import java.awt.Component; 7 9 import java.awt.Container; 8 10 import java.awt.Dimension; 11 import java.awt.KeyboardFocusManager; 9 12 import java.awt.MouseInfo; 10 13 import java.awt.Point; 11 14 import java.awt.Rectangle; 12 15 import java.awt.Robot; 16 import java.awt.Window; 13 17 import java.awt.event.ActionEvent; 14 18 import java.awt.event.InputEvent; 15 19 import java.awt.event.KeyEvent; 16 20 import java.awt.event.KeyListener; 21 import java.beans.PropertyChangeEvent; 22 import java.beans.PropertyChangeListener; 23 import java.util.EventObject; 24 import java.util.concurrent.CopyOnWriteArrayList; 17 25 import java.util.logging.Level; 18 26 import java.util.logging.Logger; 19 27 20 28 import javax.swing.AbstractAction; 21 import javax.swing.Action; 29 import javax.swing.CellEditor; 30 import javax.swing.DefaultListSelectionModel; 22 31 import javax.swing.JComponent; 23 32 import javax.swing.JTable; … … 35 44 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionCache; 36 45 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList; 46 import org.openstreetmap.josm.tools.ImageProvider; 37 47 38 48 /** … … 40 50 * 41 51 */ 42 @SuppressWarnings("serial")43 52 public class TagTable extends JTable { 44 53 45 private static Logger logger = Logger.getLogger(TagTable.class.getName());54 private static final Logger logger = Logger.getLogger(TagTable.class.getName()); 46 55 47 56 /** the table cell editor used by this table */ 48 57 private TagCellEditor editor = null; 49 58 59 /** a list of components to which focus can be transferred withouth stopping 60 * cell editing this table. 61 */ 62 private final CopyOnWriteArrayList<Component> doNotStopCellEditingWhenFocused = new CopyOnWriteArrayList<Component>(); 63 private CellEditorRemover editorRemover; 64 50 65 /** 51 66 * The table has two columns. The first column is used for editing rendering and … … 54 69 */ 55 70 static class TagTableColumnModel extends DefaultTableColumnModel { 56 57 public TagTableColumnModel() {71 public TagTableColumnModel(DefaultListSelectionModel selectionModel) { 72 setSelectionModel(selectionModel); 58 73 TableColumn col = null; 59 74 TagCellRenderer renderer = new TagCellRenderer(); … … 72 87 col.setCellRenderer(renderer); 73 88 addColumn(col); 74 75 89 } 76 90 } … … 85 99 * last cell in the table</li> 86 100 * <ul> 87 *88 * @author gubaer89 101 * 90 102 */ … … 167 179 class DeleteAction extends RunnableAction implements ListSelectionListener { 168 180 181 public DeleteAction() { 182 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete")); 183 putValue(SHORT_DESCRIPTION, tr("Delete the selection in the tag table")); 184 getSelectionModel().addListSelectionListener(this); 185 getColumnModel().getSelectionModel().addListSelectionListener(this); 186 updateEnabledState(); 187 } 188 169 189 /** 170 190 * delete a selection of tag names … … 194 214 } 195 215 196 /**197 * constructor198 */199 public DeleteAction() {200 putValue(Action.NAME, tr("Delete"));201 getSelectionModel().addListSelectionListener(this);202 getColumnModel().getSelectionModel().addListSelectionListener(this);203 }204 205 216 @Override 206 217 public void run() { 207 218 if (!isEnabled()) 208 219 return; 209 getCellEditor().stopCellEditing();210 if (getSelectedColumnCount() == 1) {220 switch(getSelectedColumnCount()) { 221 case 1: 211 222 if (getSelectedColumn() == 0) { 212 223 deleteTagNames(); … … 216 227 // should not happen 217 228 // 218 throw new IllegalStateException("unexpected selected clolumn: getSelectedColumn() is " + getSelectedColumn()); 219 } else if (getSelectedColumnCount() == 2) { 229 throw new IllegalStateException("unexpected selected column: getSelectedColumn() is " + getSelectedColumn()); 230 break; 231 case 2: 220 232 deleteTags(); 221 } 233 break; 234 } 235 236 if (isEditing()) { 237 CellEditor editor = getCellEditor(); 238 if (editor != null) { 239 editor.cancelCellEditing(); 240 } 241 } 242 222 243 TagEditorModel model = (TagEditorModel)getModel(); 223 244 if (model.getRowCount() == 0) { … … 231 252 */ 232 253 public void valueChanged(ListSelectionEvent e) { 254 updateEnabledState(); 255 } 256 257 protected void updateEnabledState() { 233 258 if (isEditing() && getSelectedColumnCount() == 1 && getSelectedRowCount() == 1) { 234 259 setEnabled(false); … … 240 265 setEnabled(false); 241 266 } 242 243 267 } 244 268 } … … 249 273 * 250 274 */ 251 class AddAction extends RunnableAction { 252 275 class AddAction extends RunnableAction implements PropertyChangeListener{ 253 276 public AddAction() { 254 putValue(Action.NAME, tr("Add")); 277 putValue(SMALL_ICON, ImageProvider.get("dialogs", "add")); 278 putValue(SHORT_DESCRIPTION, tr("Add a new tag")); 279 TagTable.this.addPropertyChangeListener(this); 280 updateEnabledState(); 255 281 } 256 282 257 283 @Override 258 284 public void run() { 259 getCellEditor().stopCellEditing(); 285 CellEditor editor = getCellEditor(); 286 if (editor != null) { 287 getCellEditor().stopCellEditing(); 288 } 260 289 ((TagEditorModel)getModel()).appendNewTag(); 261 290 final int rowIdx = getModel().getRowCount()-1; 262 291 requestFocusInCell(rowIdx, 0); 263 292 } 293 294 protected void updateEnabledState() { 295 setEnabled(TagTable.this.isEnabled()); 296 } 297 298 public void propertyChange(PropertyChangeEvent evt) { 299 updateEnabledState(); 300 } 264 301 } 265 302 … … 287 324 protected void init() { 288 325 setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 289 setCellSelectionEnabled(true); 326 //setCellSelectionEnabled(true); 327 setRowSelectionAllowed(true); 328 setColumnSelectionAllowed(true); 290 329 setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); 291 putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);292 330 293 331 // make ENTER behave like TAB … … 316 354 // 317 355 editor = new TagCellEditor(); 318 editor.setTagEditorModel((TagEditorModel)getModel());319 356 getColumnModel().getColumn(0).setCellEditor(editor); 320 357 getColumnModel().getColumn(1).setCellEditor(editor); 358 359 getSelectionModel().addListSelectionListener(new ListSelectionListener() { 360 361 public void valueChanged(ListSelectionEvent e) { 362 ListSelectionModel rm = getSelectionModel(); 363 ListSelectionModel cm = getColumnModel().getSelectionModel(); 364 } 365 }); 321 366 } 322 367 … … 327 372 * @param columnModel 328 373 */ 329 public TagTable(TableModel model ) {330 super(model, new TagTableColumnModel( ));374 public TagTable(TableModel model, DefaultListSelectionModel rowSelectionModel, DefaultListSelectionModel colSelectionModel) { 375 super(model, new TagTableColumnModel(colSelectionModel), rowSelectionModel); 331 376 init(); 332 377 } … … 430 475 } 431 476 } 477 478 public void addComponentNotStoppingCellEditing(Component component) { 479 if (component == null) return; 480 doNotStopCellEditingWhenFocused.addIfAbsent(component); 481 } 482 483 public void removeComponentNotStoppingCellEditing(Component component) { 484 if (component == null) return; 485 doNotStopCellEditingWhenFocused.remove(component); 486 } 487 488 @Override 489 public boolean editCellAt(int row, int column, EventObject e){ 490 491 // a snipped copied from the Java 1.5 implementation of JTable 492 // 493 if (cellEditor != null && !cellEditor.stopCellEditing()) 494 return false; 495 496 if (row < 0 || row >= getRowCount() || 497 column < 0 || column >= getColumnCount()) 498 return false; 499 500 if (!isCellEditable(row, column)) 501 return false; 502 503 // make sure our custom implementation of CellEditorRemover is created 504 if (editorRemover == null) { 505 KeyboardFocusManager fm = 506 KeyboardFocusManager.getCurrentKeyboardFocusManager(); 507 editorRemover = new CellEditorRemover(fm); 508 fm.addPropertyChangeListener("permanentFocusOwner", editorRemover); 509 } 510 511 // delegate to the default implementation 512 return super.editCellAt(row, column,e); 513 } 514 515 516 @Override 517 public void removeEditor() { 518 // make sure we unregister our custom implementation of CellEditorRemover 519 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 520 removePropertyChangeListener("permanentFocusOwner", editorRemover); 521 editorRemover = null; 522 super.removeEditor(); 523 } 524 525 @Override 526 public void removeNotify() { 527 // make sure we unregister our custom implementation of CellEditorRemover 528 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 529 removePropertyChangeListener("permanentFocusOwner", editorRemover); 530 editorRemover = null; 531 super.removeNotify(); 532 } 533 534 /** 535 * This is a custom implementation of the CellEditorRemover used in JTable 536 * to handle the client property <tt>terminateEditOnFocusLost</tt>. 537 * 538 * This implementation also checks whether focus is transferred to one of a list 539 * of dedicated components, see {@see TagTable#doNotStopCellEditingWhenFocused}. 540 * A typical example for such a component is a button in {@see TagEditorPanel} 541 * which isn't a child component of {@see TagTable} but which should respond to 542 * to focus transfer in a similar way to a child of TagTable. 543 * 544 */ 545 class CellEditorRemover implements PropertyChangeListener { 546 KeyboardFocusManager focusManager; 547 548 public CellEditorRemover(KeyboardFocusManager fm) { 549 this.focusManager = fm; 550 } 551 552 public void propertyChange(PropertyChangeEvent ev) { 553 if (!isEditing()) 554 return; 555 556 Component c = focusManager.getPermanentFocusOwner(); 557 while (c != null) { 558 if (c == TagTable.this) 559 // focus remains inside the table 560 return; 561 if (doNotStopCellEditingWhenFocused.contains(c)) 562 // focus remains on one of the associated components 563 return; 564 else if ((c instanceof Window) || 565 (c instanceof Applet && c.getParent() == null)) { 566 if (c == SwingUtilities.getRoot(TagTable.this)) { 567 if (!getCellEditor().stopCellEditing()) { 568 getCellEditor().cancelCellEditing(); 569 } 570 } 571 break; 572 } 573 c = c.getParent(); 574 } 575 } 576 } 432 577 }
Note: See TracChangeset
for help on using the changeset viewer.
