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

Last change on this file since 2617 was 2613, checked in by Gubaer, 14 years ago

new: global in-memory cache for downloaded changesets
new: toggle dialog for changesets
new: downloading of changesets (currently without changeset content, will follow later)

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