001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.gui.widgets;
003
004 import java.awt.event.MouseAdapter;
005 import java.awt.event.MouseEvent;
006
007 import javax.swing.JPopupMenu;
008 import javax.swing.JTable;
009 import javax.swing.ListSelectionModel;
010 import javax.swing.SwingUtilities;
011 import javax.swing.table.TableColumnModel;
012
013 import org.openstreetmap.josm.actions.ZoomToAction;
014 import org.openstreetmap.josm.data.osm.OsmPrimitive;
015 import org.openstreetmap.josm.gui.MapView;
016 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
017
018 public abstract class OsmPrimitivesTable extends JTable {
019
020 /**
021 * the data layer in whose context primitives are edited in this table
022 */
023 private OsmDataLayer layer;
024
025 /** the popup menu */
026 private JPopupMenu popupMenu;
027 private ZoomToAction zoomToAction;
028
029 public final OsmDataLayer getLayer() {
030 return layer;
031 }
032
033 public final void setLayer(OsmDataLayer layer) {
034 this.layer = layer;
035 }
036
037 public OsmPrimitivesTable(OsmPrimitivesTableModel dm, TableColumnModel cm, ListSelectionModel sm) {
038 super(dm, cm, sm);
039 addMouseListener(new PopupListener());
040 addMouseListener(new DblClickHandler());
041 }
042
043 public OsmPrimitivesTableModel getOsmPrimitivesTableModel() {
044 return (OsmPrimitivesTableModel) getModel();
045 }
046
047 /**
048 * Replies the popup menu for this table
049 *
050 * @return the popup menu
051 */
052 protected final JPopupMenu getPopUpMenu() {
053 if (popupMenu == null) {
054 popupMenu = buildPopupMenu();
055 }
056 return popupMenu;
057 }
058
059 protected abstract ZoomToAction buildZoomToAction();
060
061 protected JPopupMenu buildPopupMenu() {
062 JPopupMenu menu = new JPopupMenu();
063 zoomToAction = buildZoomToAction();
064 MapView.addLayerChangeListener(zoomToAction);
065 getSelectionModel().addListSelectionListener(zoomToAction);
066 menu.add(zoomToAction);
067 return menu;
068 }
069
070 public void unlinkAsListener() {
071 MapView.removeLayerChangeListener(zoomToAction);
072 }
073
074 public OsmPrimitive getPrimitiveInLayer(int row, OsmDataLayer layer) {
075 return getOsmPrimitivesTableModel().getReferredPrimitive(row);
076 }
077
078 protected class PopupListener extends MouseAdapter {
079 @Override
080 public void mousePressed(MouseEvent e) {
081 showPopup(e);
082 }
083
084 @Override
085 public void mouseReleased(MouseEvent e) {
086 showPopup(e);
087 }
088
089 private void showPopup(MouseEvent e) {
090 if (e.isPopupTrigger()) {
091 getPopUpMenu().show(e.getComponent(), e.getX(), e.getY());
092 }
093 }
094 }
095
096 protected class DblClickHandler extends MouseAdapter {
097
098 protected void setSelection(MouseEvent e) {
099 int row = rowAtPoint(e.getPoint());
100 if (row < 0) return;
101 OsmPrimitive primitive = getPrimitiveInLayer(row, layer);
102 if (layer != null && primitive != null) {
103 layer.data.setSelected(primitive.getPrimitiveId());
104 }
105 }
106
107 protected void addSelection(MouseEvent e) {
108 int row = rowAtPoint(e.getPoint());
109 if (row < 0) return;
110 OsmPrimitive primitive = getPrimitiveInLayer(row, layer);
111 getSelectionModel().addSelectionInterval(row, row);
112 if (layer != null && primitive != null) {
113 layer.data.addSelected(primitive.getPrimitiveId());
114 }
115 }
116
117 @Override
118 public void mouseClicked(MouseEvent e) {
119 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) {
120 if (e.isControlDown()) {
121 addSelection(e);
122 } else {
123 setSelection(e);
124 }
125 }
126 }
127 }
128 }