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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 48 - (hide annotations)
Fri Apr 17 12:49:33 2009 UTC (15 years, 10 months ago) by alfonx
File size: 22200 byte(s)


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26