source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java@ 2487

Last change on this file since 2487 was 2487, checked in by Gubaer, 14 years ago

Fixed event handling in RelationListDialog. Fixed registering/unregistering for data set events.
Synchronized model manipulation. Update of RelationListDialog due to data set events should now
always run in the EDT.
This should fix a couple of NPEs recently reported in trac.

  • Property svn:eol-style set to native
File size: 27.4 KB
Line 
1package org.openstreetmap.josm.gui.dialogs;
2
3import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.GridLayout;
8import java.awt.Point;
9import java.awt.event.ActionEvent;
10import java.awt.event.KeyEvent;
11import java.awt.event.MouseAdapter;
12import java.awt.event.MouseEvent;
13import java.util.ArrayList;
14import java.util.Collection;
15import java.util.Collections;
16import java.util.Comparator;
17import java.util.HashSet;
18import java.util.List;
19import java.util.Set;
20
21import javax.swing.AbstractAction;
22import javax.swing.AbstractListModel;
23import javax.swing.DefaultListSelectionModel;
24import javax.swing.JList;
25import javax.swing.JPanel;
26import javax.swing.JPopupMenu;
27import javax.swing.JScrollPane;
28import javax.swing.KeyStroke;
29import javax.swing.ListSelectionModel;
30import javax.swing.SwingUtilities;
31import javax.swing.event.ListSelectionEvent;
32import javax.swing.event.ListSelectionListener;
33
34import org.openstreetmap.josm.Main;
35import org.openstreetmap.josm.data.osm.DataSetListener;
36import org.openstreetmap.josm.data.osm.NameFormatter;
37import org.openstreetmap.josm.data.osm.Node;
38import org.openstreetmap.josm.data.osm.OsmPrimitive;
39import org.openstreetmap.josm.data.osm.Relation;
40import org.openstreetmap.josm.data.osm.RelationMember;
41import org.openstreetmap.josm.data.osm.Way;
42import org.openstreetmap.josm.gui.DefaultNameFormatter;
43import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
44import org.openstreetmap.josm.gui.SideButton;
45import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor;
46import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
47import org.openstreetmap.josm.gui.layer.Layer;
48import org.openstreetmap.josm.gui.layer.OsmDataLayer;
49import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
50import org.openstreetmap.josm.tools.GBC;
51import org.openstreetmap.josm.tools.ImageProvider;
52import org.openstreetmap.josm.tools.Shortcut;
53
54/**
55 * A dialog showing all known relations, with buttons to add, edit, and
56 * delete them.
57 *
58 * We don't have such dialogs for nodes, segments, and ways, because those
59 * objects are visible on the map and can be selected there. Relations are not.
60 */
61public class RelationListDialog extends ToggleDialog implements LayerChangeListener, DataSetListener {
62 //private static final Logger logger = Logger.getLogger(RelationListDialog.class.getName());
63
64 /** The display list. */
65 private JList displaylist;
66 /** the list model used */
67 private RelationListModel model;
68
69 /** the edit action */
70 private EditAction editAction;
71 /** the delete action */
72 private DeleteAction deleteAction;
73 private NewAction newAction;
74 /** the popup menu */
75 private RelationDialogPopupMenu popupMenu;
76
77 /**
78 * constructor
79 */
80 public RelationListDialog() {
81 super(tr("Relations"), "relationlist", tr("Open a list of all relations."),
82 Shortcut.registerShortcut("subwindow:relations", tr("Toggle: {0}", tr("Relations")), KeyEvent.VK_R, Shortcut.GROUP_LAYER), 150);
83
84 // create the list of relations
85 //
86 DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
87 model = new RelationListModel(selectionModel);
88 displaylist = new JList(model);
89 displaylist.setSelectionModel(selectionModel);
90 displaylist.setCellRenderer(new OsmPrimitivRenderer());
91 displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
92 displaylist.addMouseListener(new MouseEventHandler());
93 add(new JScrollPane(displaylist), BorderLayout.CENTER);
94
95 // create the panel with buttons
96 //
97 JPanel buttonPanel = new JPanel(new GridLayout(1,3));
98
99 // the new action
100 //
101 newAction = new NewAction();
102 buttonPanel.add(new SideButton(newAction), GBC.std());
103
104 // the edit action
105 //
106 editAction = new EditAction();
107 displaylist.addListSelectionListener(editAction);
108 buttonPanel.add(new SideButton(editAction), GBC.std());
109
110 // the duplicate action
111 //
112 DuplicateAction duplicateAction = new DuplicateAction();
113 displaylist.addListSelectionListener(duplicateAction);
114 buttonPanel.add(new SideButton(duplicateAction), GBC.std());
115
116 // the delete action
117 //
118 deleteAction = new DeleteAction();
119 displaylist.addListSelectionListener(deleteAction);
120 buttonPanel.add(new SideButton(deleteAction), GBC.eol());
121
122 // the select action
123 //
124 SelectAction selectAction = new SelectAction();
125 displaylist.addListSelectionListener(selectAction);
126 buttonPanel.add(new SideButton(selectAction), GBC.eol());
127
128 add(buttonPanel, BorderLayout.SOUTH);
129
130 // activate DEL in the list of relations
131 displaylist.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0), "deleteRelation");
132 displaylist.getActionMap().put("deleteRelation", deleteAction);
133
134 popupMenu = new RelationDialogPopupMenu();
135 }
136
137 @Override public void showNotify() {
138 Layer.listeners.add(this);
139 Layer.listeners.add(newAction);
140 // Register as a data set listener for the current edit layer only.
141 // See also activeLayerChanged
142 if (Main.main.getEditLayer() != null) {
143 Main.main.getEditLayer().data.addDataSetListener(this);
144 }
145 }
146
147 @Override public void hideNotify() {
148 Layer.listeners.remove(this);
149 Layer.listeners.remove(newAction);
150 Layer.listeners.add(newAction);
151 // unregistering from *all* data layer is somewhat overkill but it
152 // doesn't harm either.
153 for (OsmDataLayer layer:Main.map.mapView.getLayersOfType(OsmDataLayer.class)) {
154 layer.data.removeDataSetListener(this);
155 }
156 }
157
158 /**
159 * Initializes the relation list dialog from a layer. If <code>layer</code> is null
160 * or if it isn't an {@see OsmDataLayer} the dialog is reset to an empty dialog.
161 * Otherwise it is initialized with the list of non-deleted and visible relations
162 * in the layer's dataset.
163 *
164 * @param layer the layer. May be null.
165 */
166 protected void initFromLayer(Layer layer) {
167 if (layer == null || ! (layer instanceof OsmDataLayer)) {
168 model.setRelations(null);
169 return;
170 }
171 OsmDataLayer l = (OsmDataLayer)layer;
172 model.setRelations(l.data.getRelations());
173 if(model.getSize() > 0) {
174 setTitle(tr("Relations: {0}", model.getSize()));
175 } else {
176 setTitle(tr("Relations"));
177 }
178 }
179
180 /**
181 * Adds a selection listener to the relation list.
182 *
183 * @param listener the listener to add
184 */
185 public void addListSelectionListener(ListSelectionListener listener) {
186 displaylist.addListSelectionListener(listener);
187 }
188
189 /**
190 * Removes a selection listener from the relation list.
191 *
192 * @param listener the listener to remove
193 */
194 public void removeListSelectionListener(ListSelectionListener listener) {
195 displaylist.removeListSelectionListener(listener);
196 }
197
198 /**
199 * @return The selected relation in the list
200 */
201 private Relation getSelected() {
202 if(model.getSize() == 1) {
203 displaylist.setSelectedIndex(0);
204 }
205 return (Relation) displaylist.getSelectedValue();
206 }
207
208 /**
209 * Selects the relation <code>relation</code> in the list of relations.
210 *
211 * @param relation the relation
212 */
213 public void selectRelation(Relation relation) {
214 if (relation == null) {
215 model.setSelectedRelations(null);
216 } else {
217 model.setSelectedRelations(Collections.singletonList(relation));
218 }
219 }
220
221 class MouseEventHandler extends MouseAdapter {
222 protected void setCurrentRelationAsSelection() {
223 Main.main.getCurrentDataSet().setSelected((Relation)displaylist.getSelectedValue());
224 }
225
226 protected void editCurrentRelation() {
227 new EditAction().launchEditor(getSelected());
228 }
229
230 @Override public void mouseClicked(MouseEvent e) {
231 if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) {
232 if (e.isControlDown()) {
233 editCurrentRelation();
234 } else {
235 setCurrentRelationAsSelection();
236 }
237 }
238 }
239 private void openPopup(MouseEvent e) {
240 Point p = e.getPoint();
241 int index = displaylist.locationToIndex(p);
242 if (index < 0) return;
243 if (!displaylist.getCellBounds(index, index).contains(e.getPoint()))
244 return;
245 if (! displaylist.isSelectedIndex(index)) {
246 displaylist.setSelectedIndex(index);
247 }
248 popupMenu.show(RelationListDialog.this, p.x, p.y-3);
249 }
250 @Override public void mousePressed(MouseEvent e) {
251 if (e.isPopupTrigger()) {
252 openPopup(e);
253 }
254 }
255 @Override public void mouseReleased(MouseEvent e) {
256 if (e.isPopupTrigger()) {
257 openPopup(e);
258 }
259 }
260 }
261
262 /**
263 * The edit action
264 *
265 */
266 class EditAction extends AbstractAction implements ListSelectionListener{
267 public EditAction() {
268 putValue(SHORT_DESCRIPTION,tr( "Open an editor for the selected relation"));
269 //putValue(NAME, tr("Edit"));
270 putValue(SMALL_ICON, ImageProvider.get("dialogs", "edit"));
271 setEnabled(false);
272 }
273 protected Collection<RelationMember> getMembersForCurrentSelection(Relation r) {
274 Collection<RelationMember> members = new HashSet<RelationMember>();
275 Collection<OsmPrimitive> selection = Main.map.mapView.getEditLayer().data.getSelected();
276 for (RelationMember member: r.getMembers()) {
277 if (selection.contains(member.getMember())) {
278 members.add(member);
279 }
280 }
281 return members;
282 }
283
284 public void launchEditor(Relation toEdit) {
285 if (toEdit == null)
286 return;
287 RelationEditor.getEditor(Main.map.mapView.getEditLayer(),toEdit, getMembersForCurrentSelection(toEdit)).setVisible(true);
288 }
289
290 public void actionPerformed(ActionEvent e) {
291 if (!isEnabled())
292 return;
293 launchEditor(getSelected());
294 }
295
296 public void valueChanged(ListSelectionEvent e) {
297 setEnabled(displaylist.getSelectedIndices() != null && displaylist.getSelectedIndices().length == 1);
298 }
299 }
300
301 /**
302 * The delete action
303 *
304 */
305 class DeleteAction extends AbstractAction implements ListSelectionListener {
306 class AbortException extends Exception {}
307
308 public DeleteAction() {
309 putValue(SHORT_DESCRIPTION,tr("Delete the selected relation"));
310 //putValue(NAME, tr("Delete"));
311 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
312 setEnabled(false);
313 }
314
315 protected void deleteRelation(Relation toDelete) {
316 if (toDelete == null)
317 return;
318 org.openstreetmap.josm.actions.mapmode.DeleteAction.deleteRelation(
319 Main.main.getEditLayer(),
320 toDelete
321 );
322 }
323
324 public void actionPerformed(ActionEvent e) {
325 if (!isEnabled()) return;
326 int [] idx = displaylist.getSelectedIndices();
327 ArrayList<Relation> toDelete = new ArrayList<Relation>(idx.length);
328 for (int i: idx) {
329 toDelete.add(model.getRelation(i));
330 }
331 for (Relation r: toDelete) {
332 deleteRelation(r);
333 }
334 }
335
336 public void valueChanged(ListSelectionEvent e) {
337 setEnabled(displaylist.getSelectedIndices() != null && displaylist.getSelectedIndices().length > 0);
338 }
339 }
340
341 /**
342 * The action for creating a new relation
343 *
344 */
345 class NewAction extends AbstractAction implements LayerChangeListener{
346 public NewAction() {
347 putValue(SHORT_DESCRIPTION,tr("Create a new relation"));
348 //putValue(NAME, tr("New"));
349 putValue(SMALL_ICON, ImageProvider.get("dialogs", "addrelation"));
350 setEnabled(false);
351 }
352
353 public void run() {
354 RelationEditor.getEditor(Main.main.getEditLayer(),null, null).setVisible(true);
355 }
356
357 public void actionPerformed(ActionEvent e) {
358 run();
359 }
360
361 protected void updateEnabledState() {
362 setEnabled(Main.main != null && Main.main.getEditLayer() != null);
363 }
364
365 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
366 updateEnabledState();
367 }
368
369 public void layerAdded(Layer newLayer) {
370 updateEnabledState();
371 }
372
373 public void layerRemoved(Layer oldLayer) {
374 updateEnabledState();
375 }
376 }
377
378 /**
379 * Creates a new relation with a copy of the current editor state
380 *
381 */
382 class DuplicateAction extends AbstractAction implements ListSelectionListener {
383 public DuplicateAction() {
384 putValue(SHORT_DESCRIPTION, tr("Create a copy of this relation and open it in another editor window"));
385 putValue(SMALL_ICON, ImageProvider.get("duplicate"));
386 //putValue(NAME, tr("Duplicate"));
387 updateEnabledState();
388 }
389
390 public void launchEditorForDuplicate(Relation original) {
391 Relation copy = new Relation(original, true);
392 copy.setModified(true);
393 RelationEditor editor = RelationEditor.getEditor(
394 Main.main.getEditLayer(),
395 copy,
396 null /* no selected members */
397 );
398 editor.setVisible(true);
399 }
400
401 public void actionPerformed(ActionEvent e) {
402 if (!isEnabled())
403 return;
404 launchEditorForDuplicate(getSelected());
405 }
406
407 protected void updateEnabledState() {
408 setEnabled(displaylist.getSelectedIndices() != null && displaylist.getSelectedIndices().length == 1);
409 }
410
411 public void valueChanged(ListSelectionEvent e) {
412 updateEnabledState();
413 }
414 }
415
416 /**
417 * Sets the current selection to the list of relations selected in this dialog
418 *
419 */
420 class SelectAction extends AbstractAction implements ListSelectionListener{
421 public SelectAction() {
422 putValue(SHORT_DESCRIPTION,tr("Set the current selection to the list of selected relations"));
423 putValue(SMALL_ICON, ImageProvider.get("dialogs", "select"));
424 setEnabled(false);
425 }
426
427 public void actionPerformed(ActionEvent e) {
428 if (!isEnabled()) return;
429 int [] idx = displaylist.getSelectedIndices();
430 if (idx == null || idx.length == 0) return;
431 ArrayList<OsmPrimitive> selection = new ArrayList<OsmPrimitive>(idx.length);
432 for (int i: idx) {
433 selection.add(model.getRelation(i));
434 }
435 Main.map.mapView.getEditLayer().data.setSelected(selection);
436 }
437
438 public void valueChanged(ListSelectionEvent e) {
439 setEnabled(displaylist.getSelectedIndices() != null && displaylist.getSelectedIndices().length > 0);
440 }
441 }
442
443 /**
444 * Sets the current selection to the list of relations selected in this dialog
445 *
446 */
447 class SelectMembersAction extends AbstractAction implements ListSelectionListener{
448 public SelectMembersAction() {
449 putValue(SHORT_DESCRIPTION,tr("Select the members of all selected relations"));
450 putValue(SMALL_ICON, ImageProvider.get("selectall"));
451 putValue(NAME, tr("Select members"));
452 updateEnabledState();
453 }
454
455 public void actionPerformed(ActionEvent e) {
456 if (!isEnabled()) return;
457 List<Relation> relations = model.getSelectedRelations();
458 HashSet<OsmPrimitive> members = new HashSet<OsmPrimitive>();
459 for(Relation r: relations) {
460 members.addAll(r.getMemberPrimitives());
461 }
462 Main.map.mapView.getEditLayer().data.setSelected(members);
463 }
464
465 protected void updateEnabledState() {
466 setEnabled(displaylist.getSelectedIndices() != null && displaylist.getSelectedIndices().length > 0);
467 }
468
469 public void valueChanged(ListSelectionEvent e) {
470 updateEnabledState();
471 }
472 }
473
474 /**
475 * The action for downloading members of all selected relations
476 *
477 */
478 class DownloadMembersAction extends AbstractAction implements ListSelectionListener{
479
480 public DownloadMembersAction() {
481 putValue(SHORT_DESCRIPTION,tr("Download all members of the selected relations"));
482 putValue(NAME, tr("Download members"));
483 putValue(SMALL_ICON, ImageProvider.get("dialogs", "downloadincomplete"));
484 putValue("help", ht("/Dialog/RelationList#DownloadMembers"));
485 updateEnabledState();
486 }
487
488 protected void updateEnabledState() {
489 setEnabled(! model.getSelectedNonNewRelations().isEmpty());
490 }
491
492 public void valueChanged(ListSelectionEvent e) {
493 updateEnabledState();
494 }
495
496 public void actionPerformed(ActionEvent e) {
497 List<Relation> relations = model.getSelectedNonNewRelations();
498 if (relations.isEmpty())
499 return;
500 Main.worker.submit(new GenericRelationEditor.DownloadTask(
501 model.getSelectedNonNewRelations(),
502 Main.map.mapView.getEditLayer(), null));
503 }
504 }
505
506 /**
507 * The list model for the list of relations displayed in the relation list
508 * dialog.
509 *
510 */
511 private static class RelationListModel extends AbstractListModel {
512 private ArrayList<Relation> relations;
513 private DefaultListSelectionModel selectionModel;
514
515 public RelationListModel(DefaultListSelectionModel selectionModel) {
516 this.selectionModel = selectionModel;
517 }
518
519 public Relation getRelation(int idx) {
520 return relations.get(idx);
521 }
522
523 public synchronized void setRelations(Collection<Relation> relations) {
524 if (relations == null) {
525 this.relations = null;
526 } else {
527 this.relations = new ArrayList<Relation>(relations.size());
528 for (Relation r: relations) {
529 if (! r.isDeleted() && r.isVisible() && !r.incomplete) {
530 this.relations.add(r);
531 }
532 }
533 }
534 sort();
535 fireIntervalAdded(this, 0, getSize());
536 selectionModel.clearSelection();
537 }
538
539 public synchronized void sort() {
540 if (relations == null) return;
541 Collections.sort(
542 relations,
543 new Comparator<Relation>() {
544 NameFormatter formatter = DefaultNameFormatter.getInstance();
545
546 public int compare(Relation r1, Relation r2) {
547 return r1.getDisplayName(formatter).compareTo(r2.getDisplayName(formatter));
548 }
549 }
550 );
551 }
552
553 /**
554 * Add all relations in <code>addedPrimitives</code> to the model for the
555 * relation list dialog
556 *
557 * @param addedPrimitives the collection of added primitives. May include nodes,
558 * ways, and relations.
559 */
560 public synchronized void addRelations(Collection<? extends OsmPrimitive> addedPrimitives) {
561 if (addedPrimitives == null || addedPrimitives.isEmpty()) return;
562 boolean added = false;
563 for (OsmPrimitive p: addedPrimitives) {
564 if (! (p instanceof Relation)) {
565 continue;
566 }
567 if (relations.contains(p)) {
568 continue;
569 }
570 relations.add((Relation)p);
571 added = true;
572 }
573 if (added) {
574 List<Relation> sel = getSelectedRelations();
575 sort();
576 fireIntervalAdded(this, 0, getSize());
577 setSelectedRelations(sel);
578 }
579 }
580
581 /**
582 * Removes all relations in <code>removedPrimitives</code> from the model
583 *
584 * @param removedPrimitives the removed primitives. May include nodes, ways,
585 * and relations
586 */
587 public synchronized void removeRelations(Collection<? extends OsmPrimitive> removedPrimitives) {
588 if (removedPrimitives == null) return;
589 // extract the removed relations
590 //
591 Set<Relation> removedRelations = new HashSet<Relation>();
592 for (OsmPrimitive p: removedPrimitives) {
593 if (! (p instanceof Relation)) {
594 continue;
595 }
596 removedRelations.add((Relation)p);
597 }
598 if (removedRelations.isEmpty())
599 return;
600 int size = relations.size();
601 relations.removeAll(removedRelations);
602 if (size != relations.size()) {
603 List<Relation> sel = getSelectedRelations();
604 sort();
605 fireContentsChanged(this, 0, getSize());
606 setSelectedRelations(sel);
607 }
608 }
609
610 public Object getElementAt(int index) {
611 if (relations == null) return null;
612 return relations.get(index);
613 }
614
615 public int getSize() {
616 if (relations == null) return 0;
617 return relations.size();
618 }
619
620 public int getIndexOfRelation(Relation relation) {
621 if (relation == null) return -1;
622 return relations.indexOf(relation);
623 }
624
625 /**
626 * Replies the list of selected, non-new relations. Empty list,
627 * if there are no selected, non-new relations.
628 *
629 * @return the list of selected, non-new relations.
630 */
631 public List<Relation> getSelectedNonNewRelations() {
632 ArrayList<Relation> ret = new ArrayList<Relation>();
633 for (int i=0; i<getSize();i++) {
634 if (!selectionModel.isSelectedIndex(i)) {
635 continue;
636 }
637 if (relations.get(i).isNew()) {
638 continue;
639 }
640 ret.add(relations.get(i));
641 }
642 return ret;
643 }
644
645 /**
646 * Replies the list of selected relations. Empty list,
647 * if there are no selected relations.
648 *
649 * @return the list of selected, non-new relations.
650 */
651 public List<Relation> getSelectedRelations() {
652 ArrayList<Relation> ret = new ArrayList<Relation>();
653 for (int i=0; i<getSize();i++) {
654 if (!selectionModel.isSelectedIndex(i)) {
655 continue;
656 }
657 ret.add(relations.get(i));
658 }
659 return ret;
660 }
661
662 /**
663 * Sets the selected relations.
664 *
665 * @return sel the list of selected relations
666 */
667 public synchronized void setSelectedRelations(List<Relation> sel) {
668 selectionModel.clearSelection();
669 if (sel == null || sel.isEmpty())
670 return;
671 for (Relation r: sel) {
672 int i = relations.indexOf(r);
673 if (i<0) {
674 continue;
675 }
676 selectionModel.addSelectionInterval(i,i);
677 }
678 }
679 }
680
681 class RelationDialogPopupMenu extends JPopupMenu {
682 protected void build() {
683 // -- download members action
684 //
685 DownloadMembersAction downloadMembersAction = new DownloadMembersAction();
686 displaylist.addListSelectionListener(downloadMembersAction);
687 add(downloadMembersAction);
688
689 // -- select members action
690 //
691 SelectMembersAction selectMembersAction = new SelectMembersAction();
692 displaylist.addListSelectionListener(selectMembersAction);
693 add(selectMembersAction);
694 }
695
696 public RelationDialogPopupMenu() {
697 build();
698 }
699 }
700
701 /* ---------------------------------------------------------------------------------- */
702 /* LayerChangeListener */
703 /* ---------------------------------------------------------------------------------- */
704 public void activeLayerChange(Layer a, Layer b) {
705 initFromLayer(b);
706 if (a != null && a instanceof OsmDataLayer) {
707 ((OsmDataLayer)a).data.removeDataSetListener(this);
708 }
709 if (b != null && b instanceof OsmDataLayer) {
710 ((OsmDataLayer)b).data.addDataSetListener(this);
711 }
712
713 }
714 public void layerRemoved(Layer a) {/* irrelevant in this context */}
715 public void layerAdded(Layer a) {/* irrelevant in this context */}
716
717
718 /* ---------------------------------------------------------------------------------- */
719 /* DataSetListener */
720 /* ---------------------------------------------------------------------------------- */
721
722 public void nodeMoved(Node node) {/* irrelevant in this context */}
723
724 public void wayNodesChanged(Way way) {/* irrelevant in this context */}
725
726 public void primtivesAdded(final Collection<? extends OsmPrimitive> added) {
727 Runnable task = new Runnable() {
728 public void run() {
729 model.addRelations(added);
730 }
731 };
732 if (SwingUtilities.isEventDispatchThread()) {
733 task.run();
734 } else {
735 SwingUtilities.invokeLater(task);
736 }
737 }
738
739 public void primtivesRemoved(final Collection<? extends OsmPrimitive> removed) {
740 Runnable task = new Runnable() {
741 public void run() {
742 model.removeRelations(removed);
743 }
744 };
745 if (SwingUtilities.isEventDispatchThread()) {
746 task.run();
747 } else {
748 SwingUtilities.invokeLater(task);
749 }
750 }
751
752 public void relationMembersChanged(final Relation r) {
753 Runnable task = new Runnable() {
754 public void run() {
755 List<Relation> sel = model.getSelectedRelations();
756 model.sort();
757 model.setSelectedRelations(sel);
758 displaylist.repaint();
759 }
760 };
761 if (SwingUtilities.isEventDispatchThread()) {
762 task.run();
763 } else {
764 SwingUtilities.invokeLater(task);
765 }
766 }
767
768 public void tagsChanged(OsmPrimitive prim) {
769 if (prim == null || ! (prim instanceof Relation))
770 return;
771 Runnable task = new Runnable() {
772 public void run() {
773 // trigger a sort of the relation list because the display name may
774 // have changed
775 //
776 List<Relation> sel = model.getSelectedRelations();
777 model.sort();
778 model.setSelectedRelations(sel);
779 displaylist.repaint();
780 }
781 };
782 if (SwingUtilities.isEventDispatchThread()) {
783 task.run();
784 } else {
785 SwingUtilities.invokeLater(task);
786 }
787 }
788}
Note: See TracBrowser for help on using the repository browser.