source: josm/branch/0.5/src/org/openstreetmap/josm/gui/dialogs/RelationEditor.java@ 333

Last change on this file since 333 was 333, checked in by framm, 17 years ago

fixes

File size: 9.6 KB
Line 
1package org.openstreetmap.josm.gui.dialogs;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4import static org.xnap.commons.i18n.I18n.marktr;
5
6import java.awt.BorderLayout;
7import java.awt.Dimension;
8import java.awt.GridBagLayout;
9import java.awt.GridLayout;
10import java.awt.event.ActionEvent;
11import java.awt.event.ActionListener;
12import java.awt.event.KeyEvent;
13import java.beans.PropertyChangeEvent;
14import java.beans.PropertyChangeListener;
15import java.util.Collections;
16import java.util.Map.Entry;
17
18import javax.swing.JButton;
19import javax.swing.JFrame;
20import javax.swing.JLabel;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23import javax.swing.JScrollPane;
24import javax.swing.JTabbedPane;
25import javax.swing.JTable;
26import javax.swing.ListSelectionModel;
27import javax.swing.event.TableModelEvent;
28import javax.swing.event.TableModelListener;
29import javax.swing.table.DefaultTableModel;
30
31import org.openstreetmap.josm.Main;
32import org.openstreetmap.josm.command.AddCommand;
33import org.openstreetmap.josm.command.ChangeCommand;
34import org.openstreetmap.josm.data.osm.OsmPrimitive;
35import org.openstreetmap.josm.data.osm.Relation;
36import org.openstreetmap.josm.data.osm.RelationMember;
37import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
38import org.openstreetmap.josm.tools.GBC;
39import org.openstreetmap.josm.tools.ImageProvider;
40
41/**
42 * This dialog is for editing relations.
43 *
44 * In the basic form, it provides two tables, one with the relation tags
45 * and one with the relation members. (Relation tags can be edited through
46 * the normal properties dialog as well, if you manage to get a relation
47 * selected!)
48 *
49 * @author Frederik Ramm <frederik@remote.org>
50 *
51 */
52public class RelationEditor extends JFrame {
53
54 /**
55 * The relation that this editor is working on, and the clone made for
56 * editing.
57 */
58 private final Relation relation;
59 private final Relation clone;
60
61 /**
62 * The property data.
63 */
64 private final DefaultTableModel propertyData = new DefaultTableModel() {
65 @Override public boolean isCellEditable(int row, int column) {
66 return true;
67 }
68 @Override public Class<?> getColumnClass(int columnIndex) {
69 return String.class;
70 }
71 };
72
73 /**
74 * The membership data.
75 */
76 private final DefaultTableModel memberData = new DefaultTableModel() {
77 @Override public boolean isCellEditable(int row, int column) {
78 return column == 0;
79 }
80 @Override public Class<?> getColumnClass(int columnIndex) {
81 return columnIndex == 1 ? OsmPrimitive.class : String.class;
82 }
83 };
84
85 /**
86 * The properties and membership lists.
87 */
88 private final JTable propertyTable = new JTable(propertyData);
89 private final JTable memberTable = new JTable(memberData);
90
91 /**
92 * Creates a new relation editor for the given relation. The relation
93 * will be saved if the user selects "ok" in the editor.
94 *
95 * If no relation is given, will create an editor for a new relation.
96 *
97 * @param relation relation to edit, or null to create a new one.
98 */
99 public RelationEditor(Relation relation)
100 {
101 super(tr("Edit Relation"));
102 this.relation = relation;
103
104 if (relation == null) {
105 // create a new relation
106 this.clone = new Relation();
107 } else {
108 // edit an existing relation
109 this.clone = new Relation(relation);
110 }
111
112 getContentPane().setLayout(new BorderLayout());
113 JTabbedPane tabPane = new JTabbedPane();
114 getContentPane().add(tabPane, BorderLayout.CENTER);
115
116 // (ab)use JOptionPane to make this look familiar;
117 // hook up with JOptionPane's property change event
118 // to detect button click
119 final JOptionPane okcancel = new JOptionPane("",
120 JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null);
121 getContentPane().add(okcancel, BorderLayout.SOUTH);
122
123 okcancel.addPropertyChangeListener(new PropertyChangeListener() {
124 public void propertyChange(PropertyChangeEvent event) {
125 if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY) && event.getNewValue() != null) {
126 if ((Integer)event.getNewValue() == JOptionPane.OK_OPTION) {
127 // clicked ok!
128 if (RelationEditor.this.relation == null) {
129 Main.main.undoRedo.add(new AddCommand(clone));
130 } else if (!RelationEditor.this.relation.realEqual(clone, true)) {
131 Main.main.undoRedo.add(new ChangeCommand(RelationEditor.this.relation, clone));
132 }
133 }
134 setVisible(false);
135 }
136 }
137 });
138
139 JLabel help = new JLabel("<html><em>"+
140 "This is the basic relation editor which allows you to change the relation's tags " +
141 "as well as the members. In addition to this we should have a smart editor that " +
142 "detects the type of relationship and limits your choices in a sensible way.</em></html>");
143
144 getContentPane().add(help, BorderLayout.NORTH);
145 try { setAlwaysOnTop(true); } catch (SecurityException sx) {}
146
147 // Basic Editor panel has two blocks;
148 // a tag table at the top and a membership list below.
149
150 // setting up the properties table
151
152 propertyData.setColumnIdentifiers(new String[]{tr("Key"),tr("Value")});
153 propertyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
154 propertyData.addTableModelListener(new TableModelListener() {
155 public void tableChanged(TableModelEvent tme) {
156 if (tme.getType() == TableModelEvent.UPDATE) {
157 int row = tme.getFirstRow();
158
159 if (!(tme.getColumn() == 0 && row == propertyData.getRowCount() -1)) {
160 clone.entrySet().clear();
161 for (int i = 0; i < propertyData.getRowCount(); i++) {
162 String key = propertyData.getValueAt(i, 0).toString();
163 String value = propertyData.getValueAt(i, 1).toString();
164 if (key.length() > 0 && value.length() > 0) clone.put(key, value);
165 }
166 refreshTables();
167 }
168 }
169 }
170 });
171 propertyTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
172
173 // setting up the member table
174
175 memberData.setColumnIdentifiers(new String[]{tr("Role"),tr("Occupied By")});
176 memberTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
177 memberTable.getColumnModel().getColumn(1).setCellRenderer(new OsmPrimitivRenderer());
178 /*
179 memberTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
180 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
181 Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
182 if (c instanceof JLabel) {
183 ((OsmPrimitive)value).visit(nameVisitor);
184 ((JLabel)c).setText(nameVisitor.name);
185 }
186 return c;
187 }
188 });
189 */
190 memberData.addTableModelListener(new TableModelListener() {
191 public void tableChanged(TableModelEvent tme) {
192 if (tme.getType() == TableModelEvent.UPDATE && tme.getColumn() == 0) {
193 int row = tme.getFirstRow();
194 clone.members.get(row).role = memberData.getValueAt(row, 0).toString();
195 }
196 }
197 });
198 memberTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
199
200
201 // combine both tables and wrap them in a scrollPane
202 JPanel bothTables = new JPanel();
203 bothTables.setLayout(new GridBagLayout());
204 bothTables.add(new JLabel(tr("Tags (empty value deletes tag)")), GBC.eol().fill(GBC.HORIZONTAL));
205 bothTables.add(new JScrollPane(propertyTable), GBC.eop().fill(GBC.BOTH));
206 bothTables.add(new JLabel(tr("Members")), GBC.eol().fill(GBC.HORIZONTAL));
207 bothTables.add(new JScrollPane(memberTable), GBC.eol().fill(GBC.BOTH));
208
209 JPanel buttonPanel = new JPanel(new GridLayout(1,3));
210
211 buttonPanel.add(createButton(marktr("Add Selected"),"addselected", tr("Add all currently selected objects as members"), KeyEvent.VK_A, new ActionListener() {
212 public void actionPerformed(ActionEvent e) {
213 addSelected();
214 }
215 }));
216
217 buttonPanel.add(createButton(marktr("Delete"),"delete", tr("Remove the member in the current table row from this relation"), KeyEvent.VK_D, new ActionListener() {
218 public void actionPerformed(ActionEvent e) {
219 int row = memberTable.getSelectedRow();
220 RelationMember mem = new RelationMember();
221 mem.role = memberTable.getValueAt(row, 0).toString();
222 mem.member = (OsmPrimitive) memberTable.getValueAt(row, 1);
223 clone.members.remove(mem);
224 refreshTables();
225 }
226 }));
227
228 buttonPanel.add(createButton(marktr("Select"),"select", tr("Highlight the member from the current table row as JOSM's selection"), KeyEvent.VK_S, new ActionListener() {
229 public void actionPerformed(ActionEvent e) {
230 int row = memberTable.getSelectedRow();
231 OsmPrimitive p = (OsmPrimitive) memberTable.getValueAt(row, 1);
232 Main.ds.setSelected(Collections.singleton(p));
233 }
234 }));
235 bothTables.add(buttonPanel, GBC.eop().fill(GBC.HORIZONTAL));
236
237 tabPane.add(bothTables, "Basic");
238
239 refreshTables();
240
241 setSize(new Dimension(400, 500));
242 setLocationRelativeTo(Main.parent);
243 }
244
245 private void refreshTables() {
246
247 // re-load property data
248
249 propertyData.setRowCount(0);
250 for (Entry<String, String> e : clone.entrySet()) {
251 propertyData.addRow(new Object[]{e.getKey(), e.getValue()});
252 }
253 propertyData.addRow(new Object[]{"", ""});
254
255 // re-load membership data
256
257 memberData.setRowCount(0);
258 for (RelationMember em : clone.members) {
259 memberData.addRow(new Object[]{em.role, em.member});
260 }
261 }
262
263 private JButton createButton(String name, String iconName, String tooltip, int mnemonic, ActionListener actionListener) {
264 JButton b = new JButton(tr(name), ImageProvider.get("dialogs", iconName));
265 b.setActionCommand(name);
266 b.addActionListener(actionListener);
267 b.setToolTipText(tooltip);
268 b.setMnemonic(mnemonic);
269 b.putClientProperty("help", "Dialog/Properties/"+name);
270 return b;
271 }
272
273 private void addSelected() {
274 for (OsmPrimitive p : Main.ds.getSelected()) {
275 RelationMember em = new RelationMember();
276 em.member = p;
277 em.role = "";
278 clone.members.add(em);
279 }
280 refreshTables();
281 }
282}
Note: See TracBrowser for help on using the repository browser.