001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.widgets; 003 004import java.awt.event.MouseAdapter; 005import java.awt.event.MouseEvent; 006 007import javax.swing.JPopupMenu; 008import javax.swing.ListSelectionModel; 009import javax.swing.SwingUtilities; 010import javax.swing.table.TableColumnModel; 011 012import org.openstreetmap.josm.actions.ZoomToAction; 013import org.openstreetmap.josm.data.osm.OsmPrimitive; 014import org.openstreetmap.josm.gui.MainApplication; 015import org.openstreetmap.josm.gui.layer.OsmDataLayer; 016 017/** 018 * Table displaying OSM primitives. 019 * @since 5297 020 */ 021public abstract class OsmPrimitivesTable extends JosmTable { 022 023 /** 024 * the data layer in whose context primitives are edited in this table 025 */ 026 private transient OsmDataLayer layer; 027 028 /** the popup menu */ 029 private JPopupMenu popupMenu; 030 private ZoomToAction zoomToAction; 031 032 /** 033 * Constructs a new {@code OsmPrimitivesTable}. 034 * @param dm table model 035 * @param cm column model 036 * @param sm selection model 037 */ 038 protected OsmPrimitivesTable(OsmPrimitivesTableModel dm, TableColumnModel cm, ListSelectionModel sm) { 039 super(dm, cm, sm); 040 addMouseListener(new PopupMenuLauncher(getPopUpMenu())); 041 addMouseListener(new DblClickHandler()); 042 } 043 044 /** 045 * Returns the table model. 046 * @return the table model 047 */ 048 public OsmPrimitivesTableModel getOsmPrimitivesTableModel() { 049 return (OsmPrimitivesTableModel) getModel(); 050 } 051 052 /** 053 * Returns the data layer. 054 * @return the data layer 055 */ 056 public final OsmDataLayer getLayer() { 057 return layer; 058 } 059 060 /** 061 * Sets the data layer. 062 * @param layer the data layer 063 */ 064 public final void setLayer(OsmDataLayer layer) { 065 this.layer = layer; 066 } 067 068 /** 069 * Replies the popup menu for this table 070 * 071 * @return the popup menu 072 */ 073 protected final JPopupMenu getPopUpMenu() { 074 if (popupMenu == null) { 075 popupMenu = buildPopupMenu(); 076 } 077 return popupMenu; 078 } 079 080 protected abstract ZoomToAction buildZoomToAction(); 081 082 protected JPopupMenu buildPopupMenu() { 083 JPopupMenu menu = new JPopupMenu(); 084 zoomToAction = buildZoomToAction(); 085 getSelectionModel().addListSelectionListener(zoomToAction); 086 menu.add(zoomToAction); 087 return menu; 088 } 089 090 /** 091 * Adds all registered listeners by this table 092 * @see #unregisterListeners() 093 * @since 10454 094 */ 095 public void registerListeners() { 096 MainApplication.getLayerManager().addLayerChangeListener(zoomToAction); 097 MainApplication.getLayerManager().addActiveLayerChangeListener(zoomToAction); 098 } 099 100 /** 101 * Removes all registered listeners by this table 102 * @since 10454 103 */ 104 public void unregisterListeners() { 105 MainApplication.getLayerManager().removeLayerChangeListener(zoomToAction); 106 MainApplication.getLayerManager().removeActiveLayerChangeListener(zoomToAction); 107 } 108 109 /** 110 * Returns primitive at the specified row. 111 * @param row table row 112 * @param layer unused in this implementation, can be useful for subclasses 113 * @return primitive at the specified row 114 */ 115 public OsmPrimitive getPrimitiveInLayer(int row, OsmDataLayer layer) { 116 return getOsmPrimitivesTableModel().getReferredPrimitive(row); 117 } 118 119 protected class DblClickHandler extends MouseAdapter { 120 121 protected void setSelection(MouseEvent e) { 122 int row = rowAtPoint(e.getPoint()); 123 if (row < 0) return; 124 OsmPrimitive primitive = getPrimitiveInLayer(row, layer); 125 if (layer != null && primitive != null) { 126 layer.data.setSelected(primitive.getPrimitiveId()); 127 } 128 } 129 130 protected void addSelection(MouseEvent e) { 131 int row = rowAtPoint(e.getPoint()); 132 if (row < 0) return; 133 OsmPrimitive primitive = getPrimitiveInLayer(row, layer); 134 getSelectionModel().addSelectionInterval(row, row); 135 if (layer != null && primitive != null) { 136 layer.data.addSelected(primitive.getPrimitiveId()); 137 } 138 } 139 140 @Override 141 public void mouseClicked(MouseEvent e) { 142 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) { 143 if (e.isControlDown()) { 144 addSelection(e); 145 } else { 146 setSelection(e); 147 } 148 } 149 } 150 } 151}