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

Last change on this file since 2474 was 2391, checked in by bastiK, 14 years ago

improved Toolbar to the left:

  • removed strange left margin (in Metal L&F, see #3721: josm-default.png)
  • show scroll-buttons only if necessary
  • allow mousewheel scrolling
  • Property svn:eol-style set to native
File size: 10.6 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.awt.Dimension;
9import java.awt.event.MouseWheelListener;
10import java.awt.event.MouseWheelEvent;
11import java.util.ArrayList;
12import java.util.List;
13
14import javax.swing.AbstractButton;
15import javax.swing.Action;
16import javax.swing.BoxLayout;
17import javax.swing.ButtonGroup;
18import javax.swing.JSplitPane;
19import javax.swing.JPanel;
20import javax.swing.JToolBar;
21import javax.swing.border.Border;
22import javax.swing.plaf.basic.BasicSplitPaneUI;
23import javax.swing.plaf.basic.BasicSplitPaneDivider;
24
25import org.openstreetmap.josm.Main;
26import org.openstreetmap.josm.actions.mapmode.DeleteAction;
27import org.openstreetmap.josm.actions.mapmode.DrawAction;
28import org.openstreetmap.josm.actions.mapmode.ExtrudeAction;
29import org.openstreetmap.josm.actions.mapmode.MapMode;
30import org.openstreetmap.josm.actions.mapmode.SelectAction;
31import org.openstreetmap.josm.actions.mapmode.ZoomAction;
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 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 public BasicSplitPaneDivider createDefaultDivider() {
129 return new BasicSplitPaneDivider(this) {
130 public void setBorder(Border b) {
131 }
132 };
133 }
134 });
135
136 add(splitPane, BorderLayout.CENTER);
137
138 dialogsPanel.setLayout(new BoxLayout(dialogsPanel, BoxLayout.Y_AXIS));
139 dialogsPanel.setPreferredSize(new Dimension(Main.pref.getInteger("toggleDialogs.width",DEF_TOGGLE_DLG_WIDTH), 0));
140
141 dialogsPanel.setMinimumSize(new Dimension(24, 0));
142 mapView.setMinimumSize(new Dimension(10,0));
143
144 toolBarToggle.setFloatable(false);
145 LayerListDialog.createInstance(this);
146 addToggleDialog(LayerListDialog.getInstance());
147 addToggleDialog(new PropertiesDialog(this));
148 addToggleDialog(new HistoryDialog());
149 addToggleDialog(new SelectionListDialog());
150 if(Main.pref.getBoolean("displayfilter", false))
151 addToggleDialog(new FilterDialog());
152 addToggleDialog(new UserListDialog());
153 addToggleDialog(conflictDialog = new ConflictDialog());
154 addToggleDialog(new CommandStackDialog(this));
155 addToggleDialog(relationListDialog = new RelationListDialog());
156
157 // status line below the map
158 statusLine = new MapStatus(this);
159 }
160
161 public void selectSelectTool(boolean onlyIfModeless) {
162 if(onlyIfModeless && !Main.pref.getBoolean("modeless", false))
163 return;
164
165 selectMapMode((MapMode)getDefaultButtonAction());
166 }
167
168 public void selectDrawTool(boolean onlyIfModeless) {
169 if(onlyIfModeless && !Main.pref.getBoolean("modeless", false))
170 return;
171
172 Action drawAction = ((AbstractButton)toolBarActions.getComponent(1)).getAction();
173 selectMapMode((MapMode)drawAction);
174 }
175
176 /**
177 * Called as some kind of destructor when the last layer has been removed.
178 * Delegates the call to all Destroyables within this component (e.g. MapModes)
179 */
180 public void destroy() {
181 dialogsPanel.destroy();
182 for (int i = 0; i < toolBarActions.getComponentCount(); ++i)
183 if (toolBarActions.getComponent(i) instanceof Destroyable) {
184 ((Destroyable)toolBarActions).destroy();
185 }
186 for (int i = 0; i < toolBarToggle.getComponentCount(); ++i)
187 if (toolBarToggle.getComponent(i) instanceof Destroyable) {
188 ((Destroyable)toolBarToggle).destroy();
189 }
190
191 // remove menu entries
192 Main.main.menu.viewMenu.setVisible(false);
193
194 // MapFrame gets destroyed when the last layer is removed, but the status line background
195 // thread that collects the information doesn't get destroyed automatically.
196 if(statusLine.thread == null) return;
197 try {
198 statusLine.thread.interrupt();
199 } catch (Exception e) {}
200 }
201
202 public Action getDefaultButtonAction() {
203 return ((AbstractButton)toolBarActions.getComponent(0)).getAction();
204 }
205
206 /**
207 * Open all ToggleDialogs that have their preferences property set. Close all others.
208 */
209 public void initializeDialogsPane() {
210 dialogsPanel.initialize(allDialogs);
211 }
212
213 /**
214 * Call this to add new toggle dialogs to the left button-list
215 * @param dlg The toggle dialog. It must not be in the list already.
216 */
217 public IconToggleButton addToggleDialog(ToggleDialog dlg) {
218 IconToggleButton button = new IconToggleButton(dlg.getToggleAction());
219 toolBarToggle.add(button);
220 allDialogs.add(dlg);
221 return button;
222 }
223
224 public void addMapMode(IconToggleButton b) {
225 toolBarActions.add(b);
226 toolGroup.add(b);
227 }
228
229 /**
230 * Fires an property changed event "visible".
231 */
232 @Override public void setVisible(boolean aFlag) {
233 boolean old = isVisible();
234 super.setVisible(aFlag);
235 if (old != aFlag) {
236 firePropertyChange("visible", old, aFlag);
237 }
238 }
239
240 /**
241 * Change the operating map mode for the view. Will call unregister on the
242 * old MapMode and register on the new one.
243 * @param mapMode The new mode to set.
244 */
245 public void selectMapMode(MapMode mapMode) {
246 if (mapMode == this.mapMode)
247 return;
248 if (this.mapMode != null) {
249 this.mapMode.exitMode();
250 }
251 this.mapMode = mapMode;
252 mapMode.enterMode();
253 }
254
255 /**
256 * Fill the given panel by adding all necessary components to the different
257 * locations.
258 *
259 * @param panel The container to fill. Must have an BorderLayout.
260 */
261 public void fillPanel(Container panel) {
262 panel.add(this, BorderLayout.CENTER);
263 JToolBar jb = new JToolBar(JToolBar.VERTICAL);
264 jb.setFloatable(false);
265 jb.add(toolBarActions);
266 jb.addSeparator(new Dimension(0,10));
267 jb.add(toolBarToggle);
268 if(Main.pref.getBoolean("sidetoolbar.visible", true))
269 {
270 if(Main.pref.getBoolean("sidetoolbar.scrollable", true)) {
271 final ScrollViewport svp = new ScrollViewport(jb, ScrollViewport.VERTICAL_DIRECTION);
272 panel.add(svp, BorderLayout.WEST);
273 jb.addMouseWheelListener(new MouseWheelListener() {
274 public void mouseWheelMoved(MouseWheelEvent e) {
275 svp.scroll(0,e.getUnitsToScroll() * 5);
276 }
277 });
278 } else {
279 panel.add(jb, BorderLayout.WEST);
280 }
281 }
282 if (statusLine != null && Main.pref.getBoolean("statusline.visible", true)) {
283 panel.add(statusLine, BorderLayout.SOUTH);
284 }
285 }
286
287 /**
288 * Replies the instance of a toggle dialog of type <code>type</code> managed by this
289 * map frame
290 *
291 * @param <T>
292 * @param type the class of the toggle dialog, i.e. UserListDialog.class
293 * @return the instance of a toggle dialog of type <code>type</code> managed by this
294 * map frame; null, if no such dialog exists
295 *
296 */
297 public <T> T getToggleDialog(Class<T> type) {
298 return dialogsPanel.getToggleDialog(type);
299 }
300
301 /**
302 * Returns the current width of the (possibly resized) toggle dialog area
303 */
304 public int getToggleDlgWidth() {
305 return dialogsPanel.getWidth();
306 }
307}
Note: See TracBrowser for help on using the repository browser.