source: josm/trunk/src/org/openstreetmap/josm/gui/MapFrame.java@ 2021

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

Improved handling of toggle dialogs

  • Property svn:eol-style set to native
File size: 9.1 KB
Line 
1// License: GPL. See LICENSE file for details.
2
3package org.openstreetmap.josm.gui;
4
5import java.awt.BorderLayout;
6import java.awt.Component;
7import java.awt.Container;
8import java.util.ArrayList;
9
10import javax.swing.AbstractButton;
11import javax.swing.Action;
12import javax.swing.BoxLayout;
13import javax.swing.ButtonGroup;
14import javax.swing.JPanel;
15import javax.swing.JToolBar;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.actions.mapmode.DeleteAction;
19import org.openstreetmap.josm.actions.mapmode.DrawAction;
20import org.openstreetmap.josm.actions.mapmode.ExtrudeAction;
21import org.openstreetmap.josm.actions.mapmode.MapMode;
22import org.openstreetmap.josm.actions.mapmode.SelectAction;
23import org.openstreetmap.josm.actions.mapmode.ZoomAction;
24import org.openstreetmap.josm.gui.dialogs.CommandStackDialog;
25import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
26import org.openstreetmap.josm.gui.dialogs.HistoryDialog;
27import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
28import org.openstreetmap.josm.gui.dialogs.PropertiesDialog;
29import org.openstreetmap.josm.gui.dialogs.RelationListDialog;
30import org.openstreetmap.josm.gui.dialogs.SelectionListDialog;
31import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
32import org.openstreetmap.josm.gui.dialogs.UserListDialog;
33import org.openstreetmap.josm.tools.Destroyable;
34
35/**
36 * One Map frame with one dataset behind. This is the container gui class whose
37 * display can be set to the different views.
38 *
39 * @author imi
40 */
41public class MapFrame extends JPanel implements Destroyable {
42
43 /**
44 * The current mode, this frame operates.
45 */
46 public MapMode mapMode;
47 /**
48 * The view control displayed.
49 */
50 public MapView mapView;
51 /**
52 * The toolbar with the action icons. To add new toggle dialog actions, use addToggleDialog
53 * instead of adding directly to this list. To add a new mode use addMapMode.
54 */
55 private JToolBar toolBarActions = new JToolBar(JToolBar.VERTICAL);
56 private JToolBar toolBarToggle = new JToolBar(JToolBar.VERTICAL);
57 /**
58 * The status line below the map
59 */
60 public MapStatus statusLine;
61
62 public ConflictDialog conflictDialog;
63 /**
64 * The dialog that shows all relations and lets the user edit them.
65 */
66 public RelationListDialog relationListDialog;
67 /**
68 * The panel list of all toggle dialog icons. To add new toggle dialog actions, use addToggleDialog
69 * instead of adding directly to this list.
70 */
71 private JPanel toggleDialogs = new JPanel();
72 private ArrayList<ToggleDialog> allDialogs = new ArrayList<ToggleDialog>();
73
74 public final ButtonGroup toolGroup = new ButtonGroup();
75
76 public MapFrame() {
77 setSize(400,400);
78 setLayout(new BorderLayout());
79
80 add(mapView = new MapView(), BorderLayout.CENTER);
81
82 new FileDrop(mapView);
83
84 // show menu entry
85 Main.main.menu.viewMenu.setVisible(true);
86
87 // toolbar
88 toolBarActions.setFloatable(false);
89 addMapMode(new IconToggleButton(new SelectAction(this)));
90 addMapMode(new IconToggleButton(new DrawAction(this)));
91 addMapMode(new IconToggleButton(new ExtrudeAction(this)));
92 addMapMode(new IconToggleButton(new ZoomAction(this)));
93 addMapMode(new IconToggleButton(new DeleteAction(this)));
94
95 toolGroup.setSelected(((AbstractButton)toolBarActions.getComponent(0)).getModel(), true);
96
97 add(toggleDialogs, BorderLayout.EAST);
98 toggleDialogs.setLayout(new BoxLayout(toggleDialogs, BoxLayout.Y_AXIS));
99
100 toolBarToggle.setFloatable(false);
101 LayerListDialog.createInstance(this);
102 addToggleDialog(LayerListDialog.getInstance());
103 addToggleDialog(new PropertiesDialog(this));
104 addToggleDialog(new HistoryDialog());
105 addToggleDialog(new SelectionListDialog());
106 addToggleDialog(new UserListDialog());
107 addToggleDialog(conflictDialog = new ConflictDialog());
108 addToggleDialog(new CommandStackDialog(this));
109 addToggleDialog(relationListDialog = new RelationListDialog());
110
111 // status line below the map
112 statusLine = new MapStatus(this);
113 }
114
115 public void selectSelectTool(boolean onlyIfModeless) {
116 if(onlyIfModeless && !Main.pref.getBoolean("modeless", false))
117 return;
118
119 selectMapMode((MapMode)getDefaultButtonAction());
120 }
121
122 public void selectDrawTool(boolean onlyIfModeless) {
123 if(onlyIfModeless && !Main.pref.getBoolean("modeless", false))
124 return;
125
126 Action drawAction = ((AbstractButton)toolBarActions.getComponent(1)).getAction();
127 selectMapMode((MapMode)drawAction);
128 }
129
130 /**
131 * Called as some kind of destructor when the last layer has been removed.
132 * Delegates the call to all Destroyables within this component (e.g. MapModes)
133 */
134 public void destroy() {
135 for (ToggleDialog t : allDialogs) {
136 t.closeDetachedDialog();
137 }
138 for (int i = 0; i < toolBarActions.getComponentCount(); ++i)
139 if (toolBarActions.getComponent(i) instanceof Destroyable) {
140 ((Destroyable)toolBarActions).destroy();
141 }
142 for (int i = 0; i < toolBarToggle.getComponentCount(); ++i)
143 if (toolBarToggle.getComponent(i) instanceof Destroyable) {
144 ((Destroyable)toolBarToggle).destroy();
145 }
146
147 // remove menu entries
148 Main.main.menu.viewMenu.setVisible(false);
149
150 // MapFrame gets destroyed when the last layer is removed, but the status line background
151 // thread that collects the information doesn't get destroyed automatically.
152 if(statusLine.thread == null) return;
153 try {
154 statusLine.thread.interrupt();
155 } catch (Exception e) {}
156 }
157
158 public Action getDefaultButtonAction() {
159 return ((AbstractButton)toolBarActions.getComponent(0)).getAction();
160 }
161
162 /**
163 * Open all ToggleDialogs that have their preferences property set. Close all others.
164 */
165 public void setVisibleDialogs() {
166 toggleDialogs.removeAll();
167 for (ToggleDialog dialog: allDialogs) {
168 dialog.setVisible(false);
169 toggleDialogs.add(dialog);
170 dialog.setParent(toggleDialogs);
171 if (Main.pref.getBoolean(dialog.getPreferencePrefix()+".visible")) {
172 dialog.showDialog();
173 } else {
174 dialog.hideDialog();
175 }
176 }
177 }
178
179 /**
180 * Call this to add new toggle dialogs to the left button-list
181 * @param dlg The toggle dialog. It must not be in the list already.
182 */
183 public IconToggleButton addToggleDialog(ToggleDialog dlg) {
184 IconToggleButton button = new IconToggleButton(dlg.getToggleAction());
185 toolBarToggle.add(button);
186 allDialogs.add(dlg);
187 return button;
188 }
189
190 public void addMapMode(IconToggleButton b) {
191 toolBarActions.add(b);
192 toolGroup.add(b);
193 }
194
195 /**
196 * Fires an property changed event "visible".
197 */
198 @Override public void setVisible(boolean aFlag) {
199 boolean old = isVisible();
200 super.setVisible(aFlag);
201 if (old != aFlag) {
202 firePropertyChange("visible", old, aFlag);
203 }
204 }
205
206
207
208 /**
209 * Change the operating map mode for the view. Will call unregister on the
210 * old MapMode and register on the new one.
211 * @param mapMode The new mode to set.
212 */
213 public void selectMapMode(MapMode mapMode) {
214 if (mapMode == this.mapMode)
215 return;
216 if (this.mapMode != null) {
217 this.mapMode.exitMode();
218 }
219 this.mapMode = mapMode;
220 mapMode.enterMode();
221 }
222
223 /**
224 * Fill the given panel by adding all necessary components to the different
225 * locations.
226 *
227 * @param panel The container to fill. Must have an BorderLayout.
228 */
229 public void fillPanel(Container panel) {
230 panel.add(this, BorderLayout.CENTER);
231 JToolBar jb = new JToolBar(JToolBar.VERTICAL);
232 jb.setFloatable(false);
233 jb.add(toolBarActions);
234 jb.addSeparator();
235 jb.add(toolBarToggle);
236 if(Main.pref.getBoolean("sidetoolbar.visible", true))
237 {
238 if(Main.pref.getBoolean("sidetoolbar.scrollable", true)) {
239 panel.add(new ScrollViewport(jb, ScrollViewport.VERTICAL_DIRECTION),
240 BorderLayout.WEST);
241 } else {
242 panel.add(jb, BorderLayout.WEST);
243 }
244 }
245 if (statusLine != null && Main.pref.getBoolean("statusline.visible", true)) {
246 panel.add(statusLine, BorderLayout.SOUTH);
247 }
248 }
249
250 /**
251 * Replies the instance of a toggle dialog of type <code>type</code> managed by this
252 * map frame
253 *
254 * @param <T>
255 * @param type the class of the toggle dialog, i.e. UserListDialog.class
256 * @return the instance of a toggle dialog of type <code>type</code> managed by this
257 * map frame; null, if no such dialog exists
258 *
259 */
260 public <T> T getToggleDialog(Class<T> type) {
261 for (ToggleDialog td : allDialogs) {
262 if (type.isInstance(td))
263 return type.cast(td);
264 }
265 return null;
266 }
267}
Note: See TracBrowser for help on using the repository browser.