source: josm/trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java@ 6084

Last change on this file since 6084 was 6084, checked in by bastiK, 11 years ago

see #8902 - add missing @Override annotations (patch by shinigami)

  • Property svn:eol-style set to native
File size: 11.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.history;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagConstraints;
7import java.awt.GridBagLayout;
8import java.awt.Insets;
9import java.awt.Point;
10import java.awt.event.ActionEvent;
11import java.awt.event.MouseAdapter;
12import java.awt.event.MouseEvent;
13
14import javax.swing.AbstractAction;
15import javax.swing.JPanel;
16import javax.swing.JPopupMenu;
17import javax.swing.JScrollPane;
18import javax.swing.JTable;
19import javax.swing.ListSelectionModel;
20import javax.swing.table.TableModel;
21
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.actions.AutoScaleAction;
24import org.openstreetmap.josm.data.osm.OsmPrimitive;
25import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
26import org.openstreetmap.josm.data.osm.PrimitiveId;
27import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
28import org.openstreetmap.josm.data.osm.history.History;
29import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
30import org.openstreetmap.josm.gui.layer.OsmDataLayer;
31import org.openstreetmap.josm.gui.util.GuiHelper;
32import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
33import org.openstreetmap.josm.tools.ImageProvider;
34
35/**
36 * NodeListViewer is a UI component which displays the node list of two
37 * version of a {@link OsmPrimitive} in a {@link History}.
38 *
39 * <ul>
40 * <li>on the left, it displays the node list for the version at {@link PointInTimeType#REFERENCE_POINT_IN_TIME}</li>
41 * <li>on the right, it displays the node list for the version at {@link PointInTimeType#CURRENT_POINT_IN_TIME}</li>
42 * </ul>
43 *
44 */
45public class NodeListViewer extends JPanel {
46
47 private HistoryBrowserModel model;
48 private VersionInfoPanel referenceInfoPanel;
49 private VersionInfoPanel currentInfoPanel;
50 private AdjustmentSynchronizer adjustmentSynchronizer;
51 private SelectionSynchronizer selectionSynchronizer;
52 private NodeListPopupMenu popupMenu;
53
54 protected JScrollPane embeddInScrollPane(JTable table) {
55 JScrollPane pane = new JScrollPane(table);
56 pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
57 pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
58 adjustmentSynchronizer.participateInSynchronizedScrolling(pane.getVerticalScrollBar());
59 return pane;
60 }
61
62 protected JTable buildReferenceNodeListTable() {
63 JTable table = new JTable(
64 model.getNodeListTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME),
65 new NodeListTableColumnModel()
66 );
67 table.setName("table.referencenodelisttable");
68 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
69 selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
70 table.addMouseListener(new InternalPopupMenuLauncher());
71 table.addMouseListener(new DoubleClickAdapter(table));
72 return table;
73 }
74
75 protected JTable buildCurrentNodeListTable() {
76 JTable table = new JTable(
77 model.getNodeListTableModel(PointInTimeType.CURRENT_POINT_IN_TIME),
78 new NodeListTableColumnModel()
79 );
80 table.setName("table.currentnodelisttable");
81 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
82 selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
83 table.addMouseListener(new InternalPopupMenuLauncher());
84 table.addMouseListener(new DoubleClickAdapter(table));
85 return table;
86 }
87
88 protected void build() {
89 setLayout(new GridBagLayout());
90 GridBagConstraints gc = new GridBagConstraints();
91
92 // ---------------------------
93 gc.gridx = 0;
94 gc.gridy = 0;
95 gc.gridwidth = 1;
96 gc.gridheight = 1;
97 gc.weightx = 0.5;
98 gc.weighty = 0.0;
99 gc.insets = new Insets(5,5,5,0);
100 gc.fill = GridBagConstraints.HORIZONTAL;
101 gc.anchor = GridBagConstraints.FIRST_LINE_START;
102 referenceInfoPanel = new VersionInfoPanel(model, PointInTimeType.REFERENCE_POINT_IN_TIME);
103 add(referenceInfoPanel,gc);
104
105 gc.gridx = 1;
106 gc.gridy = 0;
107 gc.gridwidth = 1;
108 gc.gridheight = 1;
109 gc.fill = GridBagConstraints.HORIZONTAL;
110 gc.weightx = 0.5;
111 gc.weighty = 0.0;
112 gc.anchor = GridBagConstraints.FIRST_LINE_START;
113 currentInfoPanel = new VersionInfoPanel(model, PointInTimeType.CURRENT_POINT_IN_TIME);
114 add(currentInfoPanel,gc);
115
116 adjustmentSynchronizer = new AdjustmentSynchronizer();
117 selectionSynchronizer = new SelectionSynchronizer();
118
119 popupMenu = new NodeListPopupMenu();
120
121 // ---------------------------
122 gc.gridx = 0;
123 gc.gridy = 1;
124 gc.gridwidth = 1;
125 gc.gridheight = 1;
126 gc.weightx = 0.5;
127 gc.weighty = 1.0;
128 gc.fill = GridBagConstraints.BOTH;
129 gc.anchor = GridBagConstraints.NORTHWEST;
130 add(embeddInScrollPane(buildReferenceNodeListTable()),gc);
131
132 gc.gridx = 1;
133 gc.gridy = 1;
134 gc.gridwidth = 1;
135 gc.gridheight = 1;
136 gc.weightx = 0.5;
137 gc.weighty = 1.0;
138 gc.fill = GridBagConstraints.BOTH;
139 gc.anchor = GridBagConstraints.NORTHWEST;
140 add(embeddInScrollPane(buildCurrentNodeListTable()),gc);
141 }
142
143 public NodeListViewer(HistoryBrowserModel model) {
144 setModel(model);
145 build();
146 }
147
148 protected void unregisterAsObserver(HistoryBrowserModel model) {
149 if (currentInfoPanel != null) {
150 model.deleteObserver(currentInfoPanel);
151 }
152 if (referenceInfoPanel != null) {
153 model.deleteObserver(referenceInfoPanel);
154 }
155 }
156 protected void registerAsObserver(HistoryBrowserModel model) {
157 if (currentInfoPanel != null) {
158 model.addObserver(currentInfoPanel);
159 }
160 if (referenceInfoPanel != null) {
161 model.addObserver(referenceInfoPanel);
162 }
163 }
164
165 public void setModel(HistoryBrowserModel model) {
166 if (this.model != null) {
167 unregisterAsObserver(model);
168 }
169 this.model = model;
170 if (this.model != null) {
171 registerAsObserver(model);
172 }
173 }
174
175 static class NodeListPopupMenu extends JPopupMenu {
176 private final ZoomToNodeAction zoomToNodeAction;
177 private final ShowHistoryAction showHistoryAction;
178
179 public NodeListPopupMenu() {
180 zoomToNodeAction = new ZoomToNodeAction();
181 add(zoomToNodeAction);
182 showHistoryAction = new ShowHistoryAction();
183 add(showHistoryAction);
184 }
185
186 public void prepare(PrimitiveId pid){
187 zoomToNodeAction.setPrimitiveId(pid);
188 zoomToNodeAction.updateEnabledState();
189
190 showHistoryAction.setPrimitiveId(pid);
191 showHistoryAction.updateEnabledState();
192 }
193 }
194
195 static class ZoomToNodeAction extends AbstractAction {
196 private PrimitiveId primitiveId;
197
198 public ZoomToNodeAction() {
199 putValue(NAME, tr("Zoom to node"));
200 putValue(SHORT_DESCRIPTION, tr("Zoom to this node in the current data layer"));
201 putValue(SMALL_ICON, ImageProvider.get("dialogs", "zoomin"));
202 }
203
204 @Override
205 public void actionPerformed(ActionEvent e) {
206 if (!isEnabled()) return;
207 OsmPrimitive p = getPrimitiveToZoom();
208 if (p!= null) {
209 getEditLayer().data.setSelected(p.getPrimitiveId());
210 AutoScaleAction.autoScale("selection");
211 }
212 }
213
214 public void setPrimitiveId(PrimitiveId pid) {
215 this.primitiveId = pid;
216 updateEnabledState();
217 }
218
219 protected OsmDataLayer getEditLayer() {
220 try {
221 return Main.map.mapView.getEditLayer();
222 } catch(NullPointerException e) {
223 return null;
224 }
225 }
226
227 protected OsmPrimitive getPrimitiveToZoom() {
228 if (primitiveId == null) return null;
229 OsmPrimitive p = getEditLayer().data.getPrimitiveById(primitiveId);
230 return p;
231 }
232
233 public void updateEnabledState() {
234 if (getEditLayer() == null) {
235 setEnabled(false);
236 return;
237 }
238 setEnabled(getPrimitiveToZoom() != null);
239 }
240 }
241
242 static class ShowHistoryAction extends AbstractAction {
243 private PrimitiveId primitiveId;
244
245 public ShowHistoryAction() {
246 putValue(NAME, tr("Show history"));
247 putValue(SHORT_DESCRIPTION, tr("Open a history browser with the history of this node"));
248 putValue(SMALL_ICON, ImageProvider.get("dialogs", "history"));
249 }
250
251 @Override
252 public void actionPerformed(ActionEvent e) {
253 if (!isEnabled()) return;
254 run();
255 }
256
257 public void setPrimitiveId(PrimitiveId pid) {
258 this.primitiveId = pid;
259 updateEnabledState();
260 }
261
262 public void run() {
263 if (HistoryDataSet.getInstance().getHistory(primitiveId) == null) {
264 Main.worker.submit(new HistoryLoadTask().add(primitiveId));
265 }
266 Runnable r = new Runnable() {
267 @Override
268 public void run() {
269 final History h = HistoryDataSet.getInstance().getHistory(primitiveId);
270 if (h == null)
271 return;
272 GuiHelper.runInEDT(new Runnable() {
273 @Override public void run() {
274 HistoryBrowserDialogManager.getInstance().show(h);
275 }
276 });
277 }
278 };
279 Main.worker.submit(r);
280 }
281
282 public void updateEnabledState() {
283 setEnabled(primitiveId != null && primitiveId.getUniqueId() > 0);
284 }
285 }
286
287 static private PrimitiveId primitiveIdAtRow(TableModel model, int row) {
288 DiffTableModel castedModel = (DiffTableModel) model;
289 Long id = (Long)castedModel.getValueAt(row, 0).value;
290 if(id == null) return null;
291 return new SimplePrimitiveId(id, OsmPrimitiveType.NODE);
292 }
293
294 class InternalPopupMenuLauncher extends PopupMenuLauncher {
295 public InternalPopupMenuLauncher() {
296 super(popupMenu);
297 }
298
299 @Override protected int checkTableSelection(JTable table, Point p) {
300 int row = super.checkTableSelection(table, p);
301 popupMenu.prepare(primitiveIdAtRow(table.getModel(), row));
302 return row;
303 }
304 }
305
306 static class DoubleClickAdapter extends MouseAdapter {
307 private JTable table;
308 private ShowHistoryAction showHistoryAction;
309
310 public DoubleClickAdapter(JTable table) {
311 this.table = table;
312 showHistoryAction = new ShowHistoryAction();
313 }
314
315 @Override
316 public void mouseClicked(MouseEvent e) {
317 if (e.getClickCount() < 2) return;
318 int row = table.rowAtPoint(e.getPoint());
319 if(row <= 0) return;
320 PrimitiveId pid = primitiveIdAtRow(table.getModel(), row);
321 if (pid == null)
322 return;
323 showHistoryAction.setPrimitiveId(pid);
324 showHistoryAction.run();
325 }
326 }
327}
Note: See TracBrowser for help on using the repository browser.