source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java@ 3083

Last change on this file since 3083 was 3083, checked in by bastiK, 14 years ago

added svn:eol-style=native to source files

  • Property svn:eol-style set to native
File size: 8.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.relation;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Container;
7import java.awt.Dimension;
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.awt.event.MouseAdapter;
11import java.awt.event.MouseEvent;
12
13import javax.swing.AbstractAction;
14import javax.swing.JComponent;
15import javax.swing.JPopupMenu;
16import javax.swing.JTable;
17import javax.swing.JViewport;
18import javax.swing.KeyStroke;
19import javax.swing.ListSelectionModel;
20import javax.swing.SwingUtilities;
21import javax.swing.event.ListSelectionEvent;
22import javax.swing.event.ListSelectionListener;
23
24import org.openstreetmap.josm.Main;
25import org.openstreetmap.josm.actions.AutoScaleAction;
26import org.openstreetmap.josm.data.osm.OsmPrimitive;
27import org.openstreetmap.josm.gui.MapView;
28import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
29import org.openstreetmap.josm.gui.layer.Layer;
30import org.openstreetmap.josm.gui.layer.OsmDataLayer;
31
32public class MemberTable extends JTable implements IMemberModelListener {
33
34 /**
35 * the data layer in whose context relation members are edited in this table
36 */
37 protected OsmDataLayer layer;
38
39 /** the popup menu */
40 protected JPopupMenu popupMenu;
41 private ZoomToAction zoomToAction;
42
43 /**
44 * constructor
45 *
46 * @param model
47 * @param columnModel
48 */
49 public MemberTable(OsmDataLayer layer, MemberTableModel model) {
50 super(model, new MemberTableColumnModel(), model.getSelectionModel());
51 this.layer = layer;
52 model.addMemberModelListener(this);
53 init();
54
55 }
56
57 /**
58 * initialize the table
59 */
60 protected void init() {
61 setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
62 setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
63 putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
64
65 // make ENTER behave like TAB
66 //
67 getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
68 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "selectNextColumnCell");
69
70 // install custom navigation actions
71 //
72 getActionMap().put("selectNextColumnCell", new SelectNextColumnCellAction());
73 getActionMap().put("selectPreviousColumnCell", new SelectPreviousColumnCellAction());
74
75 addMouseListener(new PopupListener());
76 addMouseListener(new DblClickHandler());
77 }
78
79 @Override
80 public Dimension getPreferredSize(){
81 Container c = getParent();
82 while(c != null && ! (c instanceof JViewport)) {
83 c = c.getParent();
84 }
85 if (c != null) {
86 Dimension d = super.getPreferredSize();
87 d.width = c.getSize().width;
88 return d;
89 }
90 return super.getPreferredSize();
91 }
92
93 public void makeMemberVisible(int index) {
94 scrollRectToVisible(getCellRect(index, 0, true));
95 }
96
97 /**
98 * Action to be run when the user navigates to the next cell in the table, for instance by
99 * pressing TAB or ENTER. The action alters the standard navigation path from cell to cell: <ul>
100 * <li>it jumps over cells in the first column</li> <li>it automatically add a new empty row
101 * when the user leaves the last cell in the table</li> <ul>
102 *
103 *
104 */
105 class SelectNextColumnCellAction extends AbstractAction {
106 public void actionPerformed(ActionEvent e) {
107 run();
108 }
109
110 public void run() {
111 int col = getSelectedColumn();
112 int row = getSelectedRow();
113 if (getCellEditor() != null) {
114 getCellEditor().stopCellEditing();
115 }
116
117 if (col == 0 && row < getRowCount() - 1) {
118 row++;
119 } else if (row < getRowCount() - 1) {
120 col = 0;
121 row++;
122 }
123 changeSelection(row, col, false, false);
124 }
125 }
126
127 /**
128 * Action to be run when the user navigates to the previous cell in the table, for instance by
129 * pressing Shift-TAB
130 *
131 */
132 class SelectPreviousColumnCellAction extends AbstractAction {
133
134 public void actionPerformed(ActionEvent e) {
135 int col = getSelectedColumn();
136 int row = getSelectedRow();
137 if (getCellEditor() != null) {
138 getCellEditor().stopCellEditing();
139 }
140
141 if (col <= 0 && row <= 0) {
142 // change nothing
143 } else if (row > 0) {
144 col = 0;
145 row--;
146 }
147 changeSelection(row, col, false, false);
148 }
149 }
150
151 /**
152 * Replies the popup menu for this table
153 *
154 * @return the popup menu
155 */
156 protected JPopupMenu getPopUpMenu() {
157 if (popupMenu == null) {
158 popupMenu = new JPopupMenu();
159 zoomToAction = new ZoomToAction();
160 MapView.addLayerChangeListener(zoomToAction);
161 getSelectionModel().addListSelectionListener(zoomToAction);
162 popupMenu.add(zoomToAction);
163 }
164 return popupMenu;
165 }
166
167 public void unlinkAsListener() {
168 MapView.removeLayerChangeListener(zoomToAction);
169 }
170
171 class PopupListener extends MouseAdapter {
172 @Override
173 public void mousePressed(MouseEvent e) {
174 showPopup(e);
175 }
176
177 @Override
178 public void mouseReleased(MouseEvent e) {
179 showPopup(e);
180 }
181
182 private void showPopup(MouseEvent e) {
183 if (e.isPopupTrigger()) {
184 getPopUpMenu().show(e.getComponent(), e.getX(), e.getY());
185 }
186 }
187 }
188
189 class ZoomToAction extends AbstractAction implements LayerChangeListener, ListSelectionListener {
190 public ZoomToAction() {
191 putValue(NAME, tr("Zoom to"));
192 putValue(SHORT_DESCRIPTION, tr("Zoom to the object the first selected member refers to"));
193 updateEnabledState();
194 }
195
196 public void actionPerformed(ActionEvent e) {
197 if (! isEnabled())
198 return;
199 int rows[] = getSelectedRows();
200 if (rows == null || rows.length == 0)
201 return;
202 int row = rows[0];
203 OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
204 layer.data.setSelected(primitive);
205 AutoScaleAction action = new AutoScaleAction("selection");
206 action.autoScale();
207 }
208
209 protected void updateEnabledState() {
210 if (Main.main == null || Main.main.getEditLayer() != layer) {
211 setEnabled(false);
212 putValue(SHORT_DESCRIPTION, tr("Zooming disabled because layer of this relation is not active"));
213 return;
214 }
215 if (getSelectedRowCount() == 0) {
216 setEnabled(false);
217 putValue(SHORT_DESCRIPTION, tr("Zooming disabled because there is no selected member"));
218 return;
219 }
220 setEnabled(true);
221 putValue(SHORT_DESCRIPTION, tr("Zoom to the object the first selected member refers to"));
222 }
223
224 public void valueChanged(ListSelectionEvent e) {
225 updateEnabledState();
226 }
227
228 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
229 updateEnabledState();
230 }
231
232 public void layerAdded(Layer newLayer) {
233 updateEnabledState();
234 }
235
236 public void layerRemoved(Layer oldLayer) {
237 updateEnabledState();
238 }
239 }
240
241 protected MemberTableModel getMemberTableModel() {
242 return (MemberTableModel) getModel();
243 }
244
245 class DblClickHandler extends MouseAdapter {
246 protected void setSelection(MouseEvent e) {
247 int row = rowAtPoint(e.getPoint());
248 if (row < 0) return;
249 OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
250 getMemberTableModel().getLayer().data.setSelected(primitive.getPrimitiveId());
251 }
252
253 protected void addSelection(MouseEvent e) {
254 int row = rowAtPoint(e.getPoint());
255 if (row < 0) return;
256 OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
257 getMemberTableModel().getSelectionModel().addSelectionInterval(row, row);
258 getMemberTableModel().getLayer().data.addSelected(primitive.getPrimitiveId());
259
260 }
261
262 @Override
263 public void mouseClicked(MouseEvent e) {
264 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) {
265 if (e.isControlDown()) {
266 addSelection(e);
267 } else {
268 setSelection(e);
269 }
270 }
271 }
272 }
273}
Note: See TracBrowser for help on using the repository browser.