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 }