source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java@ 17140

Last change on this file since 17140 was 17140, checked in by GerdP, 4 years ago

see #19885: memory leak with "temporary" objects in validator and actions
Reduce number of memory leaks in RelationEditor when nothing is changed.

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.relation;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.beans.PropertyChangeListener;
7import java.beans.PropertyChangeSupport;
8import java.util.Collection;
9
10import org.openstreetmap.josm.data.osm.Relation;
11import org.openstreetmap.josm.data.osm.RelationMember;
12import org.openstreetmap.josm.gui.ExtendedDialog;
13import org.openstreetmap.josm.gui.MainApplication;
14import org.openstreetmap.josm.gui.layer.OsmDataLayer;
15import org.openstreetmap.josm.tools.CheckParameterUtil;
16
17/**
18 * Abstract relation editor.
19 * @since 1599
20 */
21public abstract class RelationEditor extends ExtendedDialog implements IRelationEditor {
22 private static final long serialVersionUID = 1L;
23
24 /** the property name for the current relation.
25 * @see #setRelation(Relation)
26 * @see #getRelation()
27 */
28 public static final String RELATION_PROP = RelationEditor.class.getName() + ".relation";
29
30 /** the property name for the current relation snapshot
31 * @see #getRelationSnapshot()
32 */
33 public static final String RELATION_SNAPSHOT_PROP = RelationEditor.class.getName() + ".relationSnapshot";
34
35 /** The relation that this editor is working on. */
36 private transient Relation relation;
37
38 /** The version of the relation when editing is started. This is null if a new relation is created. */
39 private transient Relation relationSnapshot;
40
41 /** The data layer the relation belongs to */
42 private final transient OsmDataLayer layer;
43
44 private final PropertyChangeSupport support = new PropertyChangeSupport(this);
45
46 /**
47 * Creates a new relation editor
48 *
49 * @param layer the {@link OsmDataLayer} in whose context a relation is edited. Must not be null.
50 * @param relation the relation. Can be null if a new relation is to be edited.
51 * @throws IllegalArgumentException if layer is null
52 */
53 protected RelationEditor(OsmDataLayer layer, Relation relation) {
54 super(MainApplication.getMainFrame(),
55 "",
56 new String[] {tr("Apply Changes"), tr("Cancel")},
57 false,
58 false
59 );
60 CheckParameterUtil.ensureParameterNotNull(layer, "layer");
61 this.layer = layer;
62 setRelation(relation);
63 layer.removeRecentRelation(relation);
64 }
65
66 /**
67 * This is a factory method that creates an appropriate RelationEditor instance suitable for editing the relation
68 * that was passed in as an argument.
69 *
70 * This method is guaranteed to return a working RelationEditor.
71 *
72 * @param layer the data layer the relation is a member of
73 * @param r the relation to be edited
74 * @param selectedMembers a collection of relation members which shall be selected when the editor is first launched
75 * @return an instance of RelationEditor suitable for editing that kind of relation
76 */
77 public static RelationEditor getEditor(OsmDataLayer layer, Relation r, Collection<RelationMember> selectedMembers) {
78 if (RelationDialogManager.getRelationDialogManager().isOpenInEditor(layer, r))
79 return RelationDialogManager.getRelationDialogManager().getEditorForRelation(layer, r);
80 else {
81 RelationEditor editor = new GenericRelationEditor(layer, r, selectedMembers);
82 RelationDialogManager.getRelationDialogManager().positionOnScreen(editor);
83 RelationDialogManager.getRelationDialogManager().register(layer, r, editor);
84 return editor;
85 }
86 }
87
88 /**
89 * updates the title of the relation editor
90 */
91 protected void updateTitle() {
92 if (getRelation() == null) {
93 setTitle(tr("Create new relation in layer ''{0}''", layer.getName()));
94 } else if (getRelation().isNew()) {
95 setTitle(tr("Edit new relation in layer ''{0}''", layer.getName()));
96 } else {
97 setTitle(tr("Edit relation #{0} in layer ''{1}''", relation.getId(), layer.getName()));
98 }
99 }
100
101 @Override
102 public final Relation getRelation() {
103 return relation;
104 }
105
106 @Override
107 public final void setRelation(Relation relation) {
108 setRelationSnapshot((relation == null) ? null : new Relation(relation));
109 Relation oldValue = this.relation;
110 this.relation = relation;
111 if (this.relation != oldValue) {
112 support.firePropertyChange(RELATION_PROP, oldValue, this.relation);
113 }
114 updateTitle();
115 }
116
117 @Override
118 public final OsmDataLayer getLayer() {
119 return layer;
120 }
121
122 @Override
123 public final Relation getRelationSnapshot() {
124 return relationSnapshot;
125 }
126
127 protected final void setRelationSnapshot(Relation snapshot) {
128 if (relationSnapshot != null && relationSnapshot.getDataSet() == null)
129 relationSnapshot.setMembers(null); // see #19885
130
131 Relation oldValue = relationSnapshot;
132 relationSnapshot = snapshot;
133 if (relationSnapshot != oldValue) {
134 support.firePropertyChange(RELATION_SNAPSHOT_PROP, oldValue, relationSnapshot);
135 }
136 }
137
138 @Override
139 public final boolean isDirtyRelation() {
140 return !relation.hasEqualSemanticAttributes(relationSnapshot);
141 }
142
143 /* ----------------------------------------------------------------------- */
144 /* property change support */
145 /* ----------------------------------------------------------------------- */
146
147 @Override
148 public final void addPropertyChangeListener(PropertyChangeListener listener) {
149 this.support.addPropertyChangeListener(listener);
150 }
151
152 @Override
153 public final void removePropertyChangeListener(PropertyChangeListener listener) {
154 this.support.removePropertyChangeListener(listener);
155 }
156
157 @Override
158 public void dispose() {
159 layer.setRecentRelation(relation);
160 setRelation(null);
161 super.dispose();
162 }
163}
Note: See TracBrowser for help on using the repository browser.