source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java@ 343

Last change on this file since 343 was 304, checked in by imi, 17 years ago
  • fixed a bug that nodes were not created when no data layer was loaded
  • deprecated Main.map.mapView.addLayerChangeListener.
File size: 10.1 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Component;
8import java.awt.GridLayout;
9import java.awt.Point;
10import java.awt.event.ActionEvent;
11import java.awt.event.ActionListener;
12import java.awt.event.KeyEvent;
13import java.awt.event.MouseAdapter;
14import java.awt.event.MouseEvent;
15import java.util.Collection;
16
17import javax.swing.AbstractAction;
18import javax.swing.Action;
19import javax.swing.DefaultListCellRenderer;
20import javax.swing.DefaultListModel;
21import javax.swing.Icon;
22import javax.swing.JButton;
23import javax.swing.JLabel;
24import javax.swing.JList;
25import javax.swing.JPanel;
26import javax.swing.JScrollPane;
27import javax.swing.ListSelectionModel;
28import javax.swing.UIManager;
29import javax.swing.event.ListSelectionEvent;
30import javax.swing.event.ListSelectionListener;
31
32import org.openstreetmap.josm.Main;
33import org.openstreetmap.josm.gui.MapFrame;
34import org.openstreetmap.josm.gui.MapView;
35import org.openstreetmap.josm.gui.layer.Layer;
36import org.openstreetmap.josm.gui.layer.OsmDataLayer;
37import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
38import org.openstreetmap.josm.tools.DontShowAgainInfo;
39import org.openstreetmap.josm.tools.ImageProvider;
40import org.openstreetmap.josm.tools.ImageProvider.OverlayPosition;
41
42/**
43 * A component that manages the list of all layers and react to selection changes
44 * by setting the active layer in the mapview.
45 *
46 * @author imi
47 */
48public class LayerListDialog extends ToggleDialog implements LayerChangeListener {
49
50 /**
51 * The last layerlist created. Used to update the list in the Show/Hide and Delete actions.
52 * TODO: Replace with Listener-Pattern.
53 */
54 static JList instance;
55 private JScrollPane listScrollPane;
56
57 public final static class DeleteLayerAction extends AbstractAction {
58
59 private final Layer layer;
60
61 public DeleteLayerAction(Layer layer) {
62 super(tr("Delete"), ImageProvider.get("dialogs", "delete"));
63 putValue(SHORT_DESCRIPTION, tr("Delete the selected layer."));
64 putValue("help", "Dialog/LayerList/Delete");
65 this.layer = layer;
66 }
67
68 public void actionPerformed(ActionEvent e) {
69 int sel = instance.getSelectedIndex();
70 Layer l = layer != null ? layer : (Layer)instance.getSelectedValue();
71 if (l instanceof OsmDataLayer && !DontShowAgainInfo.show("delete_layer", tr("Do you really want to delete the whole layer?")))
72 return;
73 Main.main.removeLayer(l);
74 if (sel >= instance.getModel().getSize())
75 sel = instance.getModel().getSize()-1;
76 if (instance.getSelectedValue() == null)
77 instance.setSelectedIndex(sel);
78 if (Main.map != null)
79 Main.map.mapView.setActiveLayer((Layer)instance.getSelectedValue());
80 }
81 }
82
83 public final static class ShowHideLayerAction extends AbstractAction {
84 private final Layer layer;
85
86 public ShowHideLayerAction(Layer layer) {
87 super(tr("Show/Hide"), ImageProvider.get("dialogs", "showhide"));
88 putValue(SHORT_DESCRIPTION, tr("Toggle visible state of the selected layer."));
89 putValue("help", "Dialog/LayerList/ShowHide");
90 this.layer = layer;
91 }
92
93 public void actionPerformed(ActionEvent e) {
94 Layer l = layer == null ? (Layer)instance.getSelectedValue() : layer;
95 l.visible = !l.visible;
96 Main.map.mapView.repaint();
97 instance.repaint();
98 }
99 }
100
101 public final static class ShowHideMarkerText extends AbstractAction {
102 private final Layer layer;
103
104 public ShowHideMarkerText(Layer layer) {
105 super(tr("Show/Hide Text"), ImageProvider.get("dialogs", "showhide"));
106 putValue(SHORT_DESCRIPTION, tr("Toggle visible state of the marker text."));
107 putValue("help", "Dialog/LayerList/ShowHideMarkerText");
108 this.layer = layer;
109 }
110
111 public void actionPerformed(ActionEvent e) {
112 Layer l = layer == null ? (Layer)instance.getSelectedValue() : layer;
113 String current = Main.pref.get("marker.show "+l.name,"show");
114 Main.pref.put("marker.show "+l.name, current.equalsIgnoreCase("show") ? "hide" : "show");
115 Main.map.mapView.repaint();
116 instance.repaint();
117 }
118 }
119
120 /**
121 * The data model for the list component.
122 */
123 DefaultListModel model = new DefaultListModel();
124 /**
125 * The merge action. This is only called, if the current selection and its
126 * item below are editable datasets and the merge button is clicked.
127 */
128 private final JButton mergeButton = new JButton(ImageProvider.get("dialogs", "mergedown"));
129 /**
130 * Button for moving layer up.
131 */
132 private JButton upButton = new JButton(ImageProvider.get("dialogs", "up"));
133 /**
134 * Button for moving layer down.
135 */
136 private JButton downButton = new JButton(ImageProvider.get("dialogs", "down"));
137 /**
138 * Button for delete layer.
139 */
140 private Action deleteAction = new DeleteLayerAction(null);
141
142 /**
143 * Create an layerlist and attach it to the given mapView.
144 */
145 public LayerListDialog(MapFrame mapFrame) {
146 super(tr("Layers"), "layerlist", tr("Open a list of all loaded layers."), KeyEvent.VK_L, 100);
147 instance = new JList(model);
148 listScrollPane = new JScrollPane(instance);
149 add(listScrollPane, BorderLayout.CENTER);
150 instance.setBackground(UIManager.getColor("Button.background"));
151 instance.setCellRenderer(new DefaultListCellRenderer(){
152 @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
153 Layer layer = (Layer)value;
154 JLabel label = (JLabel)super.getListCellRendererComponent(list,
155 layer.name, index, isSelected, cellHasFocus);
156 Icon icon = layer.getIcon();
157 if (!layer.visible)
158 icon = ImageProvider.overlay(icon, "overlay/invisible", OverlayPosition.SOUTHEAST);
159 label.setIcon(icon);
160 label.setToolTipText(layer.getToolTipText());
161 return label;
162 }
163 });
164
165 final MapView mapView = mapFrame.mapView;
166
167 Collection<Layer> data = mapView.getAllLayers();
168 for (Layer l : data)
169 model.addElement(l);
170
171 instance.setSelectedValue(mapView.getActiveLayer(), true);
172 instance.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
173 instance.addListSelectionListener(new ListSelectionListener(){
174 public void valueChanged(ListSelectionEvent e) {
175 if (instance.getModel().getSize() == 0)
176 return;
177 if (instance.getSelectedIndex() == -1)
178 instance.setSelectedIndex(e.getFirstIndex());
179 mapView.setActiveLayer((Layer)instance.getSelectedValue());
180 }
181 });
182 Layer.listeners.add(this);
183
184 instance.addMouseListener(new MouseAdapter(){
185 private void openPopup(MouseEvent e) {
186 Point p = listScrollPane.getMousePosition();
187 if (p == null)
188 return; // user is faster than swing with mouse movement
189 int index = instance.locationToIndex(e.getPoint());
190 Layer layer = (Layer)instance.getModel().getElementAt(index);
191 LayerListPopup menu = new LayerListPopup(instance, layer);
192 menu.show(listScrollPane, p.x, p.y-3);
193 }
194 @Override public void mousePressed(MouseEvent e) {
195 if (e.isPopupTrigger())
196 openPopup(e);
197 }
198 @Override public void mouseReleased(MouseEvent e) {
199 if (e.isPopupTrigger())
200 openPopup(e);
201 }
202 });
203
204
205 // Buttons
206 JPanel buttonPanel = new JPanel(new GridLayout(1, 5));
207
208 ActionListener upDown = new ActionListener(){
209 public void actionPerformed(ActionEvent e) {
210 Layer l = (Layer)instance.getSelectedValue();
211 int sel = instance.getSelectedIndex();
212 int selDest = e.getActionCommand().equals("up") ? sel-1 : sel+1;
213 mapView.moveLayer(l, selDest);
214 model.set(sel, model.get(selDest));
215 model.set(selDest, l);
216 instance.setSelectedIndex(selDest);
217 updateButtonEnabled();
218 mapView.repaint();
219 }
220 };
221
222 upButton.setToolTipText(tr("Move the selected layer one row up."));
223 upButton.addActionListener(upDown);
224 upButton.setActionCommand("up");
225 upButton.putClientProperty("help", "Dialog/LayerList/Up");
226 buttonPanel.add(upButton);
227
228 downButton.setToolTipText(tr("Move the selected layer one row down."));
229 downButton.addActionListener(upDown);
230 downButton.setActionCommand("down");
231 downButton.putClientProperty("help", "Dialog/LayerList/Down");
232 buttonPanel.add(downButton);
233
234 JButton showHideButton = new JButton(new ShowHideLayerAction(null));
235 showHideButton.setText("");
236 buttonPanel.add(showHideButton);
237
238 JButton deleteButton = new JButton(deleteAction);
239 deleteButton.setText("");
240 buttonPanel.add(deleteButton);
241
242 mergeButton.setToolTipText(tr("Merge the selected layer into the layer directly below."));
243 mergeButton.addActionListener(new ActionListener(){
244 public void actionPerformed(ActionEvent e) {
245 Layer lFrom = (Layer)instance.getSelectedValue();
246 Layer lTo = (Layer)model.get(instance.getSelectedIndex()+1);
247 lTo.mergeFrom(lFrom);
248 instance.setSelectedValue(lTo, true);
249 mapView.removeLayer(lFrom);
250 }
251 });
252 mergeButton.putClientProperty("help", "Dialog/LayerList/Merge");
253 buttonPanel.add(mergeButton);
254
255 add(buttonPanel, BorderLayout.SOUTH);
256
257 updateButtonEnabled();
258 }
259
260 /**
261 * Updates the state of the Buttons.
262 */
263 void updateButtonEnabled() {
264 int sel = instance.getSelectedIndex();
265 Layer l = (Layer)instance.getSelectedValue();
266 boolean enable = model.getSize() > 1;
267 enable = enable && sel < model.getSize()-1;
268 enable = enable && l.isMergable((Layer)model.get(sel+1));
269 mergeButton.setEnabled(enable);
270 upButton.setEnabled(sel > 0);
271 downButton.setEnabled(sel < model.getSize()-1);
272 deleteAction.setEnabled(!model.isEmpty());
273 }
274
275 /**
276 * Add the new layer to the list.
277 */
278 public void layerAdded(Layer newLayer) {
279 model.add(0, newLayer);
280 updateButtonEnabled();
281 }
282
283 public void layerRemoved(Layer oldLayer) {
284 model.removeElement(oldLayer);
285 if (model.isEmpty()) {
286 Layer.listeners.remove(this);
287 return;
288 }
289 if (instance.getSelectedIndex() == -1)
290 instance.setSelectedIndex(0);
291 updateButtonEnabled();
292 }
293
294 /**
295 * If the newLayer is not the actual selection, select it.
296 */
297 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
298 if (newLayer != instance.getSelectedValue())
299 instance.setSelectedValue(newLayer, true);
300 updateButtonEnabled();
301 }
302}
Note: See TracBrowser for help on using the repository browser.