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

Last change on this file since 4238 was 4238, checked in by stoecker, 13 years ago

fix #6547 - patch by Hojoe - line height in relation editor too high

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