/[schmitzm]/trunk/src/skrueger/geotools/MapPaneToolBar.java
ViewVC logotype

Contents of /trunk/src/skrueger/geotools/MapPaneToolBar.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Tue Feb 24 22:43:52 2009 UTC (16 years ago) by mojays
File size: 22534 byte(s)
First Commit, corresponds to Revision 1008 of Wikisquare-SVN
includes:
- schmitzm.* (except schmitzm.test)
- org.geotools.* (all overridden classes)
- skrueger.geotools
- skrueger.i8n
- skrueger.swing
- appl.data.LateLoadable (dependency in SCHMITZM)
- appl.data.LoadingException (dependency in SCHMITZM)
- appl.util.RasterMetaData (dependency in SCHMITZM)

1 package skrueger.geotools;
2
3 import java.awt.BorderLayout;
4 import java.awt.Dimension;
5 import java.awt.Window;
6 import java.awt.event.ActionEvent;
7 import java.util.ArrayList;
8 import java.util.LinkedList;
9 import java.util.Map;
10 import java.util.SortedMap;
11 import java.util.TreeMap;
12
13 import javax.swing.AbstractAction;
14 import javax.swing.AbstractButton;
15 import javax.swing.Action;
16 import javax.swing.BorderFactory;
17 import javax.swing.Icon;
18 import javax.swing.ImageIcon;
19 import javax.swing.JButton;
20 import javax.swing.JComponent;
21 import javax.swing.JLabel;
22 import javax.swing.JPanel;
23 import javax.swing.JSplitPane;
24 import javax.swing.JToggleButton;
25 import javax.swing.JToolBar;
26
27 import org.apache.log4j.Logger;
28
29 import schmitzm.geotools.gui.GeoMapPane;
30 import schmitzm.geotools.gui.JMapPane;
31 import schmitzm.geotools.gui.MapContextControlPane;
32 import schmitzm.geotools.gui.MapPaneStatusBar;
33 import schmitzm.geotools.map.event.JMapPaneEvent;
34 import schmitzm.geotools.map.event.JMapPaneListener;
35 import schmitzm.geotools.map.event.MapAreaChangedEvent;
36 import schmitzm.geotools.styling.ColorMapManager;
37 import schmitzm.swing.ButtonGroup;
38 import schmitzm.swing.SwingUtil;
39
40 import com.vividsolutions.jts.geom.Envelope;
41
42 /**
43 * A toolbar to controll a {@link JMapPane} (Atlas visualization). This contains two types
44 * of buttons. A group of <i>tools</i> for the mouse actions on the map represented
45 * by {@link JToggleButton JToggleButtons}, where only one tool can be activated
46 * every time. And some (general) <i>actions</i>, represented by normal
47 * {@link JButton JButtons}.
48 * @author <a href="mailto:[email protected]">Martin Schmitz</a> (University of Bonn/Germany)
49 */
50 public class MapPaneToolBar extends JToolBar {
51 private static final Logger LOGGER = Logger.getLogger(MapPaneToolBar.class.getName());
52 /** Constant for the tool "Panning" (10). */
53 public static final int TOOL_PAN = 10;
54 /** Constant for the tool "Zoom In" (30). */
55 public static final int TOOL_ZOOMIN = 30;
56 /** Constant for the tool "Zoom Out" (40). */
57 public static final int TOOL_ZOOMOUT = 40;
58 /** Constant for the tool "Info" (20). */
59 public static final int TOOL_INFO = 20;
60
61 /** Tool currently selected */
62 protected int selectedTool = TOOL_ZOOMIN;
63 /** Holds the tool buttons of the tool bar. */
64 protected SortedMap<Integer, JToggleButton> toolButtons = null;
65 /** Controls that only one tool button is activated. */
66 protected ButtonGroup toolButtonGroup = null;
67 /** Constant for the action "Zoom back" (100). */
68 public static final int ACTION_ZOOM_BACK = 100;
69 /** Constant for the action "Zoom forward" (110). */
70 public static final int ACTION_ZOOM_FORWARD = 110;
71
72 /** Holds the action buttons of the bar. */
73 protected SortedMap<Integer, JButton> actionButtons = null;
74
75 /** Holds the {@link JMapPane} this tool bar controls. */
76 protected JMapPane mapPane = null;
77
78 /**
79 * A List to remember the last Envelopes that have been watched. Used for
80 * the zoomBack- and zoomForwardButtons *
81 */
82 protected ArrayList<Envelope> lastZooms = new ArrayList<Envelope>();
83 /** Holds the index to the current element in {@link #lastZooms}. */
84 protected int zoomBackIndex = 0;
85
86 /** Listener to sniff the zoom actions on the map. */
87 protected JMapPaneListener mapPaneListener = null;
88
89 protected boolean zoomBackForwardButtonInAction;
90
91 /**
92 * Creates a new toolbar. Notice: This toolbar does nothing
93 * until {@link #setMapPane(JMapPane)} is called!
94 */
95 public MapPaneToolBar() {
96 this(null);
97 }
98
99 /**
100 * Creates a new tool bar.
101 * @param mapPane {@link JMapPane} the tool bar controls
102 */
103 public MapPaneToolBar(JMapPane mapPane) {
104 super("Control the map", JToolBar.HORIZONTAL);
105 this.toolButtons = new TreeMap<Integer,JToggleButton>();
106 this.toolButtonGroup = new ButtonGroup();
107 this.actionButtons = new TreeMap<Integer,JButton>();
108 // Create a Listener to sniff the zooms on the JMapPane
109 this.mapPaneListener = new JMapPaneListener() {
110 public void performMapPaneEvent(JMapPaneEvent e) {
111 if ( !(e instanceof MapAreaChangedEvent) )
112 return;
113
114 if ( zoomBackForwardButtonInAction ) {
115 zoomBackForwardButtonInAction = false;
116 return;
117 }
118
119 Envelope oldMapArea = ((MapAreaChangedEvent)e).getOldMapArea();
120 if (lastZooms.size() == 0 && oldMapArea != null ) {
121 lastZooms.add(oldMapArea);
122 zoomBackIndex = 1;
123 }
124
125 final Envelope mapArea = ((MapAreaChangedEvent)e).getNewMapArea();
126 if (mapArea == null)
127 return;
128
129 if (lastZooms.size() > 0 && mapArea.equals(lastZooms.get(lastZooms.size() - 1))) {
130 // LOGGER.debug("MapAreaChangedEvent ausgelassen bei der Zaehlung der Zoomschritt weil identisch");
131 return;
132 }
133
134 if (lastZooms.size() > 0)
135 while (zoomBackIndex < lastZooms.size())
136 lastZooms.remove(lastZooms.size() - 1);
137
138 lastZooms.add(mapArea);
139 zoomBackIndex = lastZooms.size();
140 setButtonEnabled(ACTION_ZOOM_BACK, lastZooms.size() > 1);
141 setButtonEnabled(ACTION_ZOOM_FORWARD, false);
142 }
143 };
144
145 setMapPane(mapPane);
146 setFloatable(false);
147 setRollover(true);
148
149 init();
150 }
151
152 /**
153 * Sets the {@link JMapPane} controlled by this tool bar.
154 * @param mapPane {@link JMapPane} to control (if {@code null} this
155 * tool bar controls NOTHING!)
156 */
157 public void setMapPane(JMapPane mapPane) {
158 // Remove listener from old MapPane
159 if ( this.mapPane != null )
160 this.mapPane.removeMapPaneListener( mapPaneListener );
161 this.mapPane = mapPane;
162 if ( this.mapPane != null && mapPaneListener != null )
163 this.mapPane.addMapPaneListener( mapPaneListener );
164 }
165
166 /**
167 * Calls {@link #initTools()} and {@link #initActions()} and then puts
168 * all tool buttons and all actions buttons to the tool bar.
169 */
170 protected void init() {
171 initTools();
172 initActions();
173 initToolBar();
174 }
175
176
177 /**
178 * Creates the tool buttons, adds them to {@link #toolButtons} and finally
179 * creates a button group for all tools. So sub-classes which override this
180 * method should FIRST add their new tool buttons to {@link #toolButtons}
181 * before calling {@code super.initTools()}.
182 */
183 protected void initTools() {
184 // Panning
185 addTool( new MapPaneToolBarAction(
186 TOOL_PAN,
187 this,
188 "",
189 new ImageIcon(MapView.class.getResource("pan.png"))
190 ), false );
191 // Info
192 addTool( new MapPaneToolBarAction(
193 TOOL_INFO,
194 this,
195 "",
196 new ImageIcon(MapView.class.getResource("info.png"))
197 ), false );
198 // Zoom in
199 addTool( new MapPaneToolBarAction(
200 TOOL_ZOOMIN,
201 this,
202 "",
203 new ImageIcon(MapView.class.getResource("zoom_in.png"))
204 ), false );
205 // Zoom out
206 addTool( new MapPaneToolBarAction(
207 TOOL_ZOOMOUT,
208 this,
209 "",
210 new ImageIcon(MapView.class.getResource("zoom_out.png"))
211 ), false );
212
213 // set the selected tool enabled
214 setSelectedTool(selectedTool);
215
216 }
217
218 /**
219 * Creates the action buttons and adds them to {@link #actionButtons}.
220 */
221 protected void initActions() {
222 // Action button to revert the last zoom
223 addAction( new MapPaneToolBarAction(
224 ACTION_ZOOM_BACK,
225 this,
226 "",
227 new ImageIcon(MapView.class.getResource("zoom_back.png"))
228 ), false);
229 setButtonEnabled( ACTION_ZOOM_BACK, false );
230
231 // Action button to redo the last zoom
232 addAction( new MapPaneToolBarAction(
233 ACTION_ZOOM_FORWARD,
234 this,
235 "",
236 new ImageIcon(MapView.class.getResource("zoom_forward.png"))
237 ), false);
238 setButtonEnabled( ACTION_ZOOM_FORWARD, false );
239 }
240
241 /**
242 * Clears the GUI of all components and adds all tool and action buttons to the
243 * tool bar.
244 */
245 protected void initToolBar() {
246 setAlignmentY( 1f );
247 removeAll();
248 // Separator to the left of the tool actions to start
249 // the tool buttons with the map (not with the coordinate grid)
250 Dimension dimension = new Dimension( 49,10);
251 addSeparator(dimension);
252 // Tool buttons
253 for (JToggleButton b : toolButtons.values())
254 add(b);
255 // Space between tool buttons and action buttons
256 Dimension dimension2 = new Dimension( 10,10);
257 this.addSeparator(dimension2);
258 // Action buttons
259 for (JButton b : actionButtons.values())
260 add(b);
261 }
262
263 /**
264 * Performs the activation of a tool.
265 * @param tool the tool to activate
266 * @param e the event of the button
267 */
268 public void performToolButton(int tool, ActionEvent e) {
269 if ( mapPane == null )
270 return;
271
272 selectedTool = tool;
273
274 switch( tool ) {
275 case TOOL_PAN:
276 // Set the mouse tool to "Panning"
277 mapPane.setWindowSelectionState(JMapPane.NONE);
278 mapPane.setState(JMapPane.PAN);
279 mapPane.setHighlight(false);
280 mapPane.setNormalCursor(SwingUtil.PAN_CURSOR);
281 break;
282 case TOOL_INFO:
283 // Set the mouse tool to "Info"
284 mapPane.setWindowSelectionState(JMapPane.NONE);
285 mapPane.setState(JMapPane.SELECT_TOP);
286 mapPane.setHighlight(true);
287 mapPane.setNormalCursor(SwingUtil.CROSSHAIR_CURSOR);
288 break;
289 case TOOL_ZOOMIN:
290 // Set the mouse tool to "Zoom in"
291 mapPane.setWindowSelectionState(JMapPane.ZOOM_IN);
292 mapPane.setState(JMapPane.ZOOM_IN);
293 mapPane.setHighlight(false);
294 mapPane.setNormalCursor(SwingUtil.ZOOMIN_CURSOR);
295 break;
296 case TOOL_ZOOMOUT:
297 // Set the mouse tool to "Zoom out"
298 mapPane.setWindowSelectionState(JMapPane.NONE);
299 mapPane.setState(JMapPane.ZOOM_OUT);
300 mapPane.setHighlight(false);
301 mapPane.setNormalCursor(SwingUtil.ZOOMOUT_CURSOR);
302 break;
303 default:
304 // Set map actions to default
305 mapPane.setWindowSelectionState(JMapPane.NONE);
306 mapPane.setState(JMapPane.NONE);
307 mapPane.setHighlight(false);
308 mapPane.setNormalCursor(null);
309 break;
310 }
311 mapPane.updateCursor();
312 }
313
314 /**
315 * Performs the action of an action button.
316 * @param tool the action
317 * @param e the event of the button
318 */
319 protected void performActionButton(int action, ActionEvent e) {
320 if ( mapPane == null )
321 return;
322
323 // Perform the action "Zoom back": Revert the last zoom
324 if ( action == ACTION_ZOOM_BACK ) {
325 if (zoomBackIndex <= 1)
326 return;
327
328 zoomBackForwardButtonInAction = true;
329 zoomBackIndex--;
330 getButton(ACTION_ZOOM_FORWARD).setEnabled(true);
331 getButton(ACTION_ZOOM_BACK).setEnabled( zoomBackIndex > 1 );
332
333 mapPane.setMapArea( lastZooms.get(zoomBackIndex-1) );
334 mapPane.refresh();
335 }
336
337 // Perform the action "Zoom forward": Redo the last zoom
338 if ( action == ACTION_ZOOM_FORWARD ) {
339 if (zoomBackIndex < lastZooms.size()) {
340 zoomBackForwardButtonInAction = true;
341 zoomBackIndex++;
342 getButton(ACTION_ZOOM_BACK).setEnabled(true);
343 getButton(ACTION_ZOOM_FORWARD).setEnabled(zoomBackIndex < lastZooms.size());
344
345 mapPane.setMapArea( lastZooms.get(zoomBackIndex-1) );
346 mapPane.refresh();
347 }
348 }
349 }
350
351
352 /**
353 * Adds a tool to the tool bar. Does nothing if a tool or action with the
354 * specified ID already exists!
355 * @param buttonAction action for the toggle button
356 * @param resetToolBar indicates whether the toolbar GUI is reset after adding
357 * the button (if adding several actions it useful only to
358 * reset the GUI for the last added tool)
359 */
360 public void addTool(MapPaneToolBarAction buttonAction, boolean resetToolBar) {
361 if ( isButtonIDUsed(buttonAction.getID()) ) {
362 LOGGER.warn("addTool(.) ignored because ID already used for tool or action: "+buttonAction.getID());
363 return;
364 }
365 JToggleButton button = new JToggleButton(buttonAction);
366 button.setBorder( BorderFactory.createRaisedBevelBorder() );
367 toolButtonGroup.add(button);
368 toolButtons.put(buttonAction.getID(), button);
369 if ( resetToolBar )
370 initToolBar();
371 }
372
373 /**
374 * Adds a tool to the tool bar and resets the toolbar GUI.
375 * @param buttonAction action for the toggle button
376 */
377 public void addTool(MapPaneToolBarAction buttonAction) {
378 addTool(buttonAction, true);
379 }
380
381 /**
382 * Adds an action to the tool bar. Does nothing if a tool or action with the
383 * specified ID already exists!
384 * @param buttonAction action for the button
385 * @param resetToolBar indicates whether the toolbar GUI is reset after adding
386 * the button (if adding several actions it useful only to
387 * reset the GUI for the last added tool)
388 */
389 public void addAction(MapPaneToolBarAction buttonAction, boolean resetToolBar) {
390 if ( isButtonIDUsed(buttonAction.getID()) ) {
391 LOGGER.warn("addAction(.) ignored because ID already used for tool or action: "+buttonAction.getID());
392 return;
393 }
394 JButton button = new JButton(buttonAction);
395 actionButtons.put( buttonAction.getID(), button );
396 if ( resetToolBar )
397 initToolBar();
398 }
399
400 /**
401 * Adds an action to the tool bar and resets the toolbar GUI.
402 * @param buttonAction action for the toggle button
403 */
404 public void addAction(MapPaneToolBarAction buttonAction) {
405 addAction(buttonAction, true);
406 }
407
408 /**
409 * Returns the button for a specific tool or action.
410 * @param id the constant for a tool
411 * @return a {@link JButton} if {@code id} specifies an {@linkplain #getActionButton(int) action button}
412 * or {@link JToogleButton} if {@code id} specifies a {@linkplain #getToolButton(int) tool button}
413 */
414 public AbstractButton getButton(int id) {
415 AbstractButton button = toolButtons.get(id);
416 if ( button == null )
417 button = actionButtons.get(id);
418 if ( button == null )
419 LOGGER.warn("Unknown tool or action ID: "+id);
420 return button;
421 }
422
423 /**
424 * Returns the button for a specific tool.
425 * @param tool the constant for a tool
426 */
427 public JToggleButton getToolButton(int tool) {
428 AbstractButton button = getButton(tool);
429 if ( button != null && !(button instanceof JToggleButton) ) {
430 LOGGER.warn("ID specifies no tool: "+tool);
431 button = null;
432 }
433 return (JToggleButton)button;
434 }
435
436 /**
437 * Returns the button for a specific action.
438 * @param action the constant an action
439 */
440 public JButton getActionButton(int action) {
441 AbstractButton button = getButton(action);
442 if ( button != null && !(button instanceof JButton) ) {
443 LOGGER.warn("ID specifies no action: "+action);
444 button = null;
445 }
446 return (JButton)button;
447
448 }
449
450 /**
451 * Sets the selected tool.
452 * @param tool ID of the tool
453 */
454 public void setSelectedTool(Integer tool) {
455 if ( tool == null )
456 toolButtonGroup.setUnselected();
457
458 JToggleButton button = getToolButton(tool);
459 if ( button == null )
460 return;
461 button.setSelected( true );
462 button.getAction().actionPerformed(null);
463 }
464
465 /**
466 * Returns the selected tool.
467 * @return -1 if no tool is active
468 */
469 public int getSelectedTool() {
470 if ( toolButtonGroup.getSelectedButton() == null )
471 return -1;
472 return selectedTool;
473 }
474
475 /**
476 * Sets whether a tool or action is activated or not. The visible property
477 * of the button is not affected.
478 * @param id tool or actionID
479 * @param enabled if {@code true} the tool becomes available
480 */
481 public void setButtonEnabled(int id, boolean enabled) {
482 AbstractButton button = getButton(id);
483 if ( button == null )
484 return;
485 button.setEnabled( enabled );
486 }
487
488 /**
489 * Sets whether a tool or action is activated or not.
490 * @param id tool or actionID
491 * @param enabled if {@code true} the tool becomes available
492 * @param hideOnDisable if {@code true} the button is also hidden if
493 * {@code enabled} is {@code false}
494 */
495 public void setButtonEnabled(int id, boolean enabled, boolean hideOnDisable) {
496 AbstractButton button = getButton(id);
497 if ( button == null )
498 return;
499 button.setEnabled( enabled );
500 // if button is enabled, it becomes visible anyway
501 // if button is disabled and the "hide" option is set, it is also hidden
502 if ( enabled )
503 button.setVisible( true );
504 else
505 button.setVisible( !hideOnDisable );
506 }
507
508 /**
509 * Checks whether a ID is already used for a tool or action.
510 * @param tool tool ID
511 */
512 public boolean isButtonIDUsed(int id) {
513 return toolButtons.get(id) != null || actionButtons.get(id) != null;
514 }
515
516 /**
517 * Checks whether a tool is activated.
518 * @param tool tool ID
519 * @return {@code false} if an unknown ID is specified
520 */
521 public boolean isButtonEnabled(int id) {
522 AbstractButton button = getButton(id);
523 if ( button != null )
524 return button.isEnabled();
525 return false;
526 }
527
528 /**
529 * Sets the activation for all tools.
530 * @param enabled if {@code true} all tools becomes available
531 * @param hideOnDisable if {@code true} the buttons are also hidden if
532 * {@code enabled} is {@code false}
533 */
534 public void setAllToolsEnabled(boolean enabled, boolean hideOnDisable) {
535 for (int tool : toolButtons.keySet())
536 setButtonEnabled(tool,enabled,hideOnDisable);
537 }
538
539 /**
540 * Sets the activation for all actions.
541 * @param enabled if {@code true} all actions becomes available
542 * @param hideOnDisable if {@code true} the buttons are also hidden if
543 * {@code enabled} is {@code false}
544 */
545 public void setAllActionsEnabled(boolean enabled, boolean hideOnDisable) {
546 for (int tool : actionButtons.keySet())
547 setButtonEnabled(tool,enabled,hideOnDisable);
548 }
549
550 /**
551 * Returns the maximum ID of tools.
552 */
553 public int getMaxToolID() {
554 return toolButtons.lastKey();
555 }
556
557 /**
558 * Returns the minimum ID of tools.
559 */
560 public int getMinToolID() {
561 return toolButtons.firstKey();
562 }
563
564 /**
565 * Returns the maximum ID of actions.
566 */
567 public int getMaxActionID() {
568 return actionButtons.lastKey();
569 }
570
571 /**
572 * Returns the minimum ID of actions.
573 */
574 public int getMinActionID() {
575 return actionButtons.firstKey();
576 }
577
578 /**
579 * Extends the {@link AbstractAction} with maintaining an ID and
580 * the {@link MapPaneToolBar} the actions controls.
581 * Additionally this class automatically calls {@link MapPaneToolBar#performToolButton(int, ActionEvent)}
582 * or {@link MapPaneToolBar#performActionButton(int, ActionEvent)}
583 * depending on whether the action is added via {@link MapPaneToolBar#addTool(MapPaneToolBarAction)}
584 * or {@link MapPaneToolBar#addAction(MapPaneToolBarAction)}.
585 * @author <a href="mailto:[email protected]">Martin Schmitz</a> (University of Bonn/Germany)
586 */
587 public static class MapPaneToolBarAction extends AbstractAction {
588 /** The ID of the action */
589 protected int id = -1;
590 /** The tool bar, this action is made for. */
591 protected MapPaneToolBar toolBar = null;
592
593 /**
594 * Creates a new action with a dummy description and no icon.
595 * @param id unique ID for the action
596 * @param toolBar toolbar this action is made for
597 */
598 public MapPaneToolBarAction(int id, MapPaneToolBar toolBar) {
599 this(id,toolBar,""+id);
600 }
601
602 /**
603 * Creates a new action without an icon.
604 * @param id unique ID for the action
605 * @param toolBar toolbar this action is made for
606 * @param name description used for buttons or menus
607 */
608 public MapPaneToolBarAction(int id, MapPaneToolBar toolBar, String name) {
609 this(id,toolBar,name,null);
610 }
611
612 /**
613 * Creates a new action.
614 * @param id unique ID for the action
615 * @param toolBar toolbar this action is made for
616 * @param name description used for buttons or menus
617 * @param icon icon used for buttons or menus
618 */
619 public MapPaneToolBarAction(int id, MapPaneToolBar toolBar, String name, Icon icon) {
620 super(name,icon);
621 this.id = id;
622 this.toolBar = toolBar;
623 }
624
625 /**
626 * Calls {@link MapPaneToolBar#performToolButton(int, ActionEvent)}
627 * or {@link MapPaneToolBar#performActionButton(int, ActionEvent)}
628 * depending on whether the action is added to the toolbar via
629 * {@link MapPaneToolBar#addTool(MapPaneToolBarAction)}
630 * or {@link MapPaneToolBar#addAction(MapPaneToolBarAction)}.
631 */
632 public void actionPerformed(ActionEvent e) {
633 if ( toolBar.toolButtons.get(id) != null )
634 toolBar.performToolButton(id, e);
635 if ( toolBar.actionButtons.get(id) != null )
636 toolBar.performActionButton(id, e);
637 }
638
639 /**
640 * Returns the (unique) id of this action.
641 * @return
642 */
643 public int getID() {
644 return id;
645 }
646 }
647 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26