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

Last change on this file since 2043 was 2043, checked in by Gubaer, 15 years ago

fixed #3076: Member columns don't auto-resize when the relation editor is resized

File size: 7.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.event.ListSelectionEvent;
21import javax.swing.event.ListSelectionListener;
22import javax.swing.table.TableColumnModel;
23
24import org.openstreetmap.josm.Main;
25import org.openstreetmap.josm.actions.AutoScaleAction;
26import org.openstreetmap.josm.data.osm.DataSet;
27import org.openstreetmap.josm.data.osm.OsmPrimitive;
28import org.openstreetmap.josm.gui.layer.Layer;
29import org.openstreetmap.josm.gui.layer.OsmDataLayer;
30import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
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
42 /**
43 * constructor
44 *
45 * @param model
46 * @param columnModel
47 */
48 public MemberTable(OsmDataLayer layer, MemberTableModel model) {
49 super(model, new MemberTableColumnModel(), model.getSelectionModel());
50 this.layer = layer;
51 model.addMemberModelListener(this);
52 init();
53
54 }
55
56 /**
57 * initialize the table
58 */
59 protected void init() {
60 setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
61 setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
62 putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
63
64 // make ENTER behave like TAB
65 //
66 getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
67 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "selectNextColumnCell");
68
69 // install custom navigation actions
70 //
71 getActionMap().put("selectNextColumnCell", new SelectNextColumnCellAction());
72 getActionMap().put("selectPreviousColumnCell", new SelectPreviousColumnCellAction());
73
74 addMouseListener(new PopupListener());
75 }
76
77 @Override
78 public Dimension getPreferredSize(){
79 Container c = getParent();
80 while(c != null && ! (c instanceof JViewport)) {
81 c = c.getParent();
82 }
83 if (c != null) {
84 Dimension d = super.getPreferredSize();
85 d.width = c.getSize().width;
86 return d;
87 }
88 return super.getPreferredSize();
89 }
90
91 public void makeMemberVisible(int index) {
92 scrollRectToVisible(getCellRect(index, 0, true));
93 }
94
95 /**
96 * Action to be run when the user navigates to the next cell in the table, for instance by
97 * pressing TAB or ENTER. The action alters the standard navigation path from cell to cell: <ul>
98 * <li>it jumps over cells in the first column</li> <li>it automatically add a new empty row
99 * when the user leaves the last cell in the table</li> <ul>
100 *
101 *
102 */
103 class SelectNextColumnCellAction extends AbstractAction {
104 public void actionPerformed(ActionEvent e) {
105 run();
106 }
107
108 public void run() {
109 int col = getSelectedColumn();
110 int row = getSelectedRow();
111 if (getCellEditor() != null) {
112 getCellEditor().stopCellEditing();
113 }
114
115 if (col == 0 && row < getRowCount() - 1) {
116 row++;
117 } else if (row < getRowCount() - 1) {
118 col = 0;
119 row++;
120 }
121 changeSelection(row, col, false, false);
122 }
123 }
124
125 /**
126 * Action to be run when the user navigates to the previous cell in the table, for instance by
127 * pressing Shift-TAB
128 *
129 */
130 class SelectPreviousColumnCellAction extends AbstractAction {
131
132 public void actionPerformed(ActionEvent e) {
133 int col = getSelectedColumn();
134 int row = getSelectedRow();
135 if (getCellEditor() != null) {
136 getCellEditor().stopCellEditing();
137 }
138
139 if (col <= 0 && row <= 0) {
140 // change nothing
141 } else if (row > 0) {
142 col = 0;
143 row--;
144 }
145 changeSelection(row, col, false, false);
146 }
147 }
148
149 /**
150 * creates the popup men
151 */
152 protected void createPopupMenu() {
153 popupMenu = new JPopupMenu();
154 ZoomToAction zoomToAction = new ZoomToAction();
155 Layer.listeners.add(zoomToAction);
156 getSelectionModel().addListSelectionListener(zoomToAction);
157 popupMenu.add(zoomToAction);
158 }
159
160 /**
161 * Replies the popup menu for this table
162 *
163 * @return the popup menu
164 */
165 protected JPopupMenu getPopUpMenu() {
166 if (popupMenu == null) {
167 createPopupMenu();
168 }
169 return popupMenu;
170 }
171
172 class PopupListener extends MouseAdapter {
173 @Override
174 public void mousePressed(MouseEvent e) {
175 showPopup(e);
176 }
177
178 @Override
179 public void mouseReleased(MouseEvent e) {
180 showPopup(e);
181 }
182
183 private void showPopup(MouseEvent e) {
184 if (e.isPopupTrigger()) {
185 getPopUpMenu().show(e.getComponent(), e.getX(), e.getY());
186 }
187 }
188 }
189
190 class ZoomToAction extends AbstractAction implements LayerChangeListener, ListSelectionListener {
191 public ZoomToAction() {
192 putValue(NAME, tr("Zoom to"));
193 putValue(SHORT_DESCRIPTION, tr("Zoom to primitive the first selected member refers to"));
194 updateEnabledState();
195 }
196
197 public void actionPerformed(ActionEvent e) {
198 if (! isEnabled())
199 return;
200 int rows[] = getSelectedRows();
201 if (rows == null || rows.length == 0)
202 return;
203 int row = rows[0];
204 OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
205 layer.data.setSelected(primitive);
206 DataSet.fireSelectionChanged(layer.data.getSelected());
207 AutoScaleAction action = new AutoScaleAction("selection");
208 action.autoScale();
209 }
210
211 protected void updateEnabledState() {
212 if (Main.main == null || Main.main.getEditLayer() != layer) {
213 setEnabled(false);
214 putValue(SHORT_DESCRIPTION, tr("Zooming disabled because layer of this relation is not active"));
215 return;
216 }
217 if (getSelectedRowCount() == 0) {
218 setEnabled(false);
219 putValue(SHORT_DESCRIPTION, tr("Zooming disabled because there is no selected member"));
220 return;
221 }
222 setEnabled(true);
223 putValue(SHORT_DESCRIPTION, tr("Zoom to primitive the first selected member refers to"));
224 }
225
226 public void valueChanged(ListSelectionEvent e) {
227 updateEnabledState();
228 }
229
230 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
231 updateEnabledState();
232 }
233
234 public void layerAdded(Layer newLayer) {
235 updateEnabledState();
236 }
237
238 public void layerRemoved(Layer oldLayer) {
239 updateEnabledState();
240 }
241 }
242
243 protected MemberTableModel getMemberTableModel() {
244 return (MemberTableModel) getModel();
245 }
246}
Note: See TracBrowser for help on using the repository browser.