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

Last change on this file since 3327 was 3327, checked in by jttt, 14 years ago

Fix some of "Keystroke %s is already assigned to %s, will be overridden by %s" warnings

  • 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(layer.data), 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.autoScale("selection");
206 }
207
208 protected void updateEnabledState() {
209 if (Main.main == null || Main.main.getEditLayer() != layer) {
210 setEnabled(false);
211 putValue(SHORT_DESCRIPTION, tr("Zooming disabled because layer of this relation is not active"));
212 return;
213 }
214 if (getSelectedRowCount() == 0) {
215 setEnabled(false);
216 putValue(SHORT_DESCRIPTION, tr("Zooming disabled because there is no selected member"));
217 return;
218 }
219 setEnabled(true);
220 putValue(SHORT_DESCRIPTION, tr("Zoom to the object the first selected member refers to"));
221 }
222
223 public void valueChanged(ListSelectionEvent e) {
224 updateEnabledState();
225 }
226
227 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
228 updateEnabledState();
229 }
230
231 public void layerAdded(Layer newLayer) {
232 updateEnabledState();
233 }
234
235 public void layerRemoved(Layer oldLayer) {
236 updateEnabledState();
237 }
238 }
239
240 protected MemberTableModel getMemberTableModel() {
241 return (MemberTableModel) getModel();
242 }
243
244 class DblClickHandler extends MouseAdapter {
245 protected void setSelection(MouseEvent e) {
246 int row = rowAtPoint(e.getPoint());
247 if (row < 0) return;
248 OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
249 getMemberTableModel().getLayer().data.setSelected(primitive.getPrimitiveId());
250 }
251
252 protected void addSelection(MouseEvent e) {
253 int row = rowAtPoint(e.getPoint());
254 if (row < 0) return;
255 OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
256 getMemberTableModel().getSelectionModel().addSelectionInterval(row, row);
257 getMemberTableModel().getLayer().data.addSelected(primitive.getPrimitiveId());
258
259 }
260
261 @Override
262 public void mouseClicked(MouseEvent e) {
263 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) {
264 if (e.isControlDown()) {
265 addSelection(e);
266 } else {
267 setSelection(e);
268 }
269 }
270 }
271 }
272}
Note: See TracBrowser for help on using the repository browser.