/[schmitzm]/branches/1.0-gt2-2.6/src/skrueger/geotools/MapPaneToolBar.java
ViewVC logotype

Contents of /branches/1.0-gt2-2.6/src/skrueger/geotools/MapPaneToolBar.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 445 - (show annotations)
Wed Oct 7 13:17:02 2009 UTC (15 years, 4 months ago) by alfonx
File size: 28101 byte(s)
* GP: * Do not allow NaN values in zoom back/forward Envelopes
* Extra check against unlimited while loop in JMapPane.bestAllowedMapArea
1 /*******************************************************************************
2 * Copyright (c) 2009 Martin O. J. Schmitz.
3 *
4 * This file is part of the SCHMITZM library - a collection of utility
5 * classes based on Java 1.6, focusing (not only) on Java Swing
6 * and the Geotools library.
7 *
8 * The SCHMITZM project is hosted at:
9 * http://wald.intevation.org/projects/schmitzm/
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 3
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License (license.txt)
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 * or try this link: http://www.gnu.org/licenses/lgpl.html
25 *
26 * Contributors:
27 * Martin O. J. Schmitz - initial API and implementation
28 * Stefan A. Krüger - additional utility classes
29 ******************************************************************************/
30 package skrueger.geotools;
31
32 import java.awt.Color;
33 import java.awt.Graphics;
34 import java.awt.event.ActionEvent;
35 import java.awt.event.ActionListener;
36 import java.util.ArrayList;
37 import java.util.HashSet;
38 import java.util.Locale;
39 import java.util.Set;
40 import java.util.SortedMap;
41 import java.util.TreeMap;
42
43 import javax.swing.AbstractAction;
44 import javax.swing.AbstractButton;
45 import javax.swing.Action;
46 import javax.swing.BorderFactory;
47 import javax.swing.Icon;
48 import javax.swing.ImageIcon;
49 import javax.swing.JButton;
50 import javax.swing.JComponent;
51 import javax.swing.JToggleButton;
52 import javax.swing.JToolBar;
53
54 import org.apache.log4j.Logger;
55
56 import schmitzm.geotools.gui.JMapPane;
57 import schmitzm.geotools.map.event.JMapPaneEvent;
58 import schmitzm.geotools.map.event.JMapPaneListener;
59 import schmitzm.geotools.map.event.MapAreaChangedEvent;
60 import schmitzm.lang.LangUtil;
61 import schmitzm.lang.ResourceProvider;
62 import schmitzm.swing.ButtonGroup;
63 import schmitzm.swing.SwingUtil;
64
65 import com.vividsolutions.jts.geom.Envelope;
66
67 /**
68 * A toolbar to control an {@link JMapPane} (Atlas visualization). This contains
69 * two types of buttons. A group of <i>tools</i> for the mouse actions on the
70 * map represented by {@link JToggleButton JToggleButtons}, where only one tool
71 * can be activated every time. And some (general) <i>actions</i>, represented
72 * by normal {@link JButton JButtons}.
73 *
74 * @author <a href="mailto:[email protected]">Martin Schmitz</a>
75 * (University of Bonn/Germany)
76 * @version 1.2 Stefan Krüger
77 */
78 public class MapPaneToolBar extends JToolBar {
79 private static final Logger LOGGER = Logger.getLogger(MapPaneToolBar.class
80 .getName());
81
82 public static ResourceProvider RESOURCE = new ResourceProvider(LangUtil
83 .extendPackagePath(MapPaneToolBar.class,
84 "resource.locales.mapPaneToolbar"), Locale.ENGLISH);
85
86 public static String R(String key, Object... values) {
87 return RESOURCE.getString(key, values);
88 }
89
90 /** Constant for the tool "Panning" (10). */
91 public static final int TOOL_PAN = 10;
92 /** Constant for the tool "Info" (20). */
93 public static final int TOOL_INFO = 20;
94 public static final int SEPERATOR0 = 99;
95
96 /** Constant for the tool "Zoom In" (110). */
97 public static final int TOOL_ZOOMIN = 110;
98 /** Constant for the tool "Zoom Out" (120). */
99 public static final int TOOL_ZOOMOUT = 120;
100 /** Constant for the action "Zoom back" (130). */
101 public static final int ACTION_ZOOM_BACK = 130;
102 /** Constant for the action "Zoom forward" (140). */
103 public static final int ACTION_ZOOM_FORWARD = 140;
104 public static final int SEPERATOR1 = 199;
105
106 /**
107 * Constant for the tool "Selection Reset" which clears the selection (240).
108 */
109 public static final int TOOL_SELECTION_CLEAR = 240;
110
111 /**
112 * Constant for the tool "Select" which sets the Selection to the selected
113 * features (210).
114 */
115 public static final int TOOL_SELECTION_SET = 210;
116 /**
117 * Constant for the tool "Selection add" which adds the features to the
118 * Selection (220).
119 */
120 public static final int TOOL_SELECTION_ADD = 220;
121 /**
122 * Constant for the tool "Selection subtract" which removes the selected
123 * features from the selection (230).
124 */
125 public static final int TOOL_SELECTION_REMOVE = 230;
126
127 public static final int ACTION_CHARTS = 401;
128
129 /** Tool currently selected */
130 protected int selectedTool = TOOL_ZOOMIN;
131
132 /** Holds the tool buttons of the tool bar. */
133 final protected SortedMap<Integer, JComponent> toolAndActionButtons = new TreeMap<Integer, JComponent>();
134 /** Controls that only one tool button is activated. */
135 protected ButtonGroup toolButtonGroup = null;
136
137 // SK: Musste ich ändern damit man Tools und Actions in der Reihenfolge
138 // mischen kann.
139 // /** Holds the action buttons of the bar. */
140 // protected SortedMap<Integer, JButton> actionButtons = null;
141
142 /** Holds the {@link JMapPane} this tool bar controls. */
143 protected JMapPane mapPane = null;
144
145 /**
146 * A List to remember the last Envelopes that have been watched. Used for
147 * the zoomBack- and zoomForwardButtons *
148 */
149 protected ArrayList<Envelope> lastZooms = new ArrayList<Envelope>();
150 /** Holds the index to the current element in {@link #lastZooms}. */
151 protected int zoomBackIndex = 0;
152
153 /** Listener to sniff the zoom actions on the map. */
154 protected JMapPaneListener mapPaneListener = null;
155
156 protected boolean zoomBackForwardButtonInAction;
157
158 /** Listeners what want to be informed about a change of the selected tool **/
159 protected Set<MapPaneToolSelectedListener> toolSelectionListeners = new HashSet<MapPaneToolSelectedListener>();
160
161 /** This listener is added to all {@link JToggleButton} **/
162 private final ActionListener toolSelectedListener = new ActionListener() {
163
164 @Override
165 public void actionPerformed(ActionEvent e) {
166 JToggleButton tb = (JToggleButton) e.getSource();
167
168 // Inform the listeners about a newly selected tool
169 for (MapPaneToolSelectedListener l : toolSelectionListeners) {
170 l.toolSelected(Integer.valueOf(tb.getName()));
171 }
172 }
173
174 };
175
176 /**
177 * Creates a new toolbar. Notice: This toolbar does nothing until
178 * {@link #setMapPane(JMapPane)} is called!
179 */
180 public MapPaneToolBar() {
181 this(null);
182 }
183
184 public void addButtonSelectedListener(MapPaneToolSelectedListener listener) {
185 toolSelectionListeners.add(listener);
186 }
187
188 public void removeButtonSelectedListener(
189 MapPaneToolSelectedListener listener) {
190 toolSelectionListeners.remove(listener);
191 }
192
193 /**
194 * Creates a new tool bar.
195 *
196 * @param mapPane
197 * {@link JMapPane} the tool bar controls
198 */
199 public MapPaneToolBar(JMapPane mapPane) {
200 super("Control the map", JToolBar.HORIZONTAL);
201
202 // I want to see nothing on the background
203 setOpaque(false);
204 setBorder(null);
205
206 this.toolButtonGroup = new ButtonGroup();
207
208 // Create a Listener to listen to the zooms on the JMapPane
209 this.mapPaneListener = new JMapPaneListener() {
210 public void performMapPaneEvent(JMapPaneEvent e) {
211 if (!(e instanceof MapAreaChangedEvent))
212 return;
213
214 if (zoomBackForwardButtonInAction) {
215 zoomBackForwardButtonInAction = false;
216 return;
217 }
218
219 final MapAreaChangedEvent mapAreaChangedEvent = (MapAreaChangedEvent) e;
220 Envelope oldMapArea = mapAreaChangedEvent.getOldMapArea();
221
222 final Envelope mapArea = mapAreaChangedEvent.getNewMapArea();
223 if (mapArea == null || mapArea.equals(oldMapArea)
224 || Double.isNaN(mapArea.getMinX())
225 || Double.isNaN(mapArea.getMaxX())
226 || Double.isNaN(mapArea.getMinY())
227 || Double.isNaN(mapArea.getMaxY())) {
228 // If the MapArea didn't change... we don't want to register
229 // it as a zoom action.
230 return;
231 }
232
233 if (lastZooms.size() == 0
234 && oldMapArea != null
235 && !oldMapArea.isNull()
236 && !(Double.isNaN(oldMapArea.getMinX())
237 || Double.isNaN(oldMapArea.getMaxX())
238 || Double.isNaN(oldMapArea.getMinY()) || Double
239 .isNaN(oldMapArea.getMaxY()))) {
240 lastZooms.add(oldMapArea);
241 zoomBackIndex = 1;
242 }
243 if (mapArea == null)
244 return;
245
246 if (lastZooms.size() > 0
247 && mapArea.equals(lastZooms.get(lastZooms.size() - 1))) {
248 // LOGGER.debug("MapAreaChangedEvent ausgelassen bei der Zaehlung der Zoomschritt weil identisch");
249 return;
250 }
251
252 if (lastZooms.size() > 0)
253 while (zoomBackIndex < lastZooms.size())
254 lastZooms.remove(lastZooms.size() - 1);
255
256 lastZooms.add(mapArea);
257 zoomBackIndex = lastZooms.size();
258 setButtonEnabled(ACTION_ZOOM_BACK, lastZooms.size() > 1);
259 setButtonEnabled(ACTION_ZOOM_FORWARD, false);
260 }
261 };
262
263 setMapPane(mapPane);
264 setFloatable(false);
265 setRollover(true);
266
267 init();
268 }
269
270 /**
271 * Sets the {@link JMapPane} controlled by this tool bar.
272 *
273 * @param mapPane
274 * {@link JMapPane} to control (if {@code null} this tool bar
275 * controls NOTHING!)
276 */
277 public void setMapPane(JMapPane mapPane) {
278 // Remove listener from old MapPane
279 if (this.mapPane != null)
280 this.mapPane.removeMapPaneListener(mapPaneListener);
281 this.mapPane = mapPane;
282 if (this.mapPane != null && mapPaneListener != null)
283 this.mapPane.addMapPaneListener(mapPaneListener);
284 }
285
286 /**
287 * Calls {@link #initToolsAndActions()} and {@link #initActions()} and then
288 * puts all tool buttons and all actions buttons to the tool bar.
289 */
290 protected void init() {
291
292 initToolsAndActions();
293
294 addSeparator(SEPERATOR0, new JToolBar.Separator());
295 addSeparator(SEPERATOR1, new JToolBar.Separator());
296
297 initToolBar();
298 }
299
300 /**
301 * Creates the tool buttons and action buttons and seperators, adds them to
302 * {@link #toolAndActionButtons} and finally creates a button group for all
303 * tools. So sub-classes which override this method should FIRST add their
304 * new tool buttons to {@link #toolAndActionButtons} before calling {@code
305 * super.initTools()}.
306 */
307 protected void initToolsAndActions() {
308 // Panning
309 addTool(new MapPaneToolBarAction(TOOL_PAN, this, "", new ImageIcon(
310 MapView.class.getResource("resource/icons/pan.png")),
311 R("MapPaneButtons.Pan.TT")), false);
312 // Info
313 addTool(new MapPaneToolBarAction(TOOL_INFO, this, "", new ImageIcon(
314 MapView.class.getResource("resource/icons/info.png")),
315 R("MapPaneButtons.Info.TT")), false);
316
317 // Zoom in
318 addTool(new MapPaneToolBarAction(TOOL_ZOOMIN, this, "", new ImageIcon(
319 MapView.class.getResource("resource/icons/zoom_in.png")),
320 R("MapPaneButtons.ZoomIn.TT")), false);
321 // Zoom out
322 addTool(new MapPaneToolBarAction(TOOL_ZOOMOUT, this, "", new ImageIcon(
323 MapView.class.getResource("resource/icons/zoom_out.png")),
324 R("MapPaneButtons.ZoomOut.TT")), false);
325
326 // Action button to revert the last zoom
327 addAction(new MapPaneToolBarAction(ACTION_ZOOM_BACK, this, "",
328 new ImageIcon(MapView.class
329 .getResource("resource/icons/zoom_back.png")),
330 R("MapPaneButtons.LastZoom.TT")), false);
331 setButtonEnabled(ACTION_ZOOM_BACK, false);
332
333 // Action button to redo the last zoom
334 addAction(new MapPaneToolBarAction(ACTION_ZOOM_FORWARD, this, "",
335 new ImageIcon(MapView.class
336 .getResource("resource/icons/zoom_forward.png")),
337 R("MapPaneButtons.NextZoom.TT")), false);
338 setButtonEnabled(ACTION_ZOOM_FORWARD, false);
339
340 // set the selected tool enabled
341 setSelectedTool(selectedTool);
342
343 }
344
345 @Override
346 public void paint(Graphics g) {
347 super.paint(g);
348 }
349
350 /**
351 * Clears the GUI of all components and adds all tool and action buttons to
352 * the tool bar.
353 */
354 public void initToolBar() {
355 // setOpaque(true);
356 //
357 // setAlignmentY(1f);
358 // setAlignmentX(0.5f);
359 removeAll();
360
361 // // Separator to the left of the tool actions to start
362 // // the tool buttons with the map (not with the coordinate grid)
363 // Dimension dimension = new Dimension(49, 10);
364 // addSeparator(dimension);
365
366 // Tool buttons
367 for (Integer bKey : toolAndActionButtons.keySet()) {
368
369 JComponent b = toolAndActionButtons.get(bKey);
370
371 if (b instanceof JToggleButton) {
372 JToggleButton tb = (JToggleButton) b;
373 tb.setName(bKey.toString());
374 tb.addActionListener(toolSelectedListener);
375 }
376
377 add(b);
378 }
379
380 if (!toolAndActionButtons.containsKey(selectedTool)) {
381 /**
382 * This might be a bit specific, but IF selection buttons are
383 * available, select one of them.. if not, select the INFO tool.
384 */
385
386 if (toolAndActionButtons.containsKey(TOOL_SELECTION_SET)) {
387 setSelectedTool(TOOL_SELECTION_SET);
388 } else if (toolAndActionButtons.containsKey(TOOL_INFO)) {
389 setSelectedTool(TOOL_INFO);
390 } else {
391 // TODO What to do now?!
392 setSelectedTool(null);
393 }
394
395 }
396
397 revalidate();
398 repaint();
399 }
400
401 // Space between tool buttons and action buttons
402 // SK: Seperators are now als manages like actions and tools
403 // Dimension dimension2 = new Dimension( 10,10);
404 // this.addSeparator(dimension2);
405
406 // // Action buttons
407 // for (JButton b : actionButtons.values())
408 // add(b);
409 // }
410
411 /**
412 * Performs the activation of a tool.
413 *
414 * @param tool
415 * the tool to activate
416 * @param e
417 * the event of the button
418 */
419 public void performToolButton(int tool, ActionEvent e) {
420 if (mapPane == null)
421 return;
422
423 selectedTool = tool;
424
425 switch (tool) {
426 case TOOL_PAN:
427 // Set the mouse tool to "Panning"
428 mapPane.setWindowSelectionState(JMapPane.NONE);
429 mapPane.setState(JMapPane.PAN);
430 mapPane.setNormalCursor(SwingUtil.PAN_CURSOR);
431 break;
432 case TOOL_INFO:
433 // Set the mouse tool to "Info"
434 mapPane.setWindowSelectionState(JMapPane.NONE);
435 mapPane.setState(JMapPane.SELECT_TOP); // Why not:
436 // JMapPane.SELECT_TOP_ONEONLY
437 // properly removed it to save
438 // performance
439 mapPane.setNormalCursor(SwingUtil.CROSSHAIR_CURSOR);
440 break;
441 case TOOL_ZOOMIN:
442 // Set the mouse tool to "Zoom in"
443 mapPane.setWindowSelectionState(JMapPane.ZOOM_IN);
444 mapPane.setState(JMapPane.ZOOM_IN);
445 mapPane.setNormalCursor(SwingUtil.ZOOMIN_CURSOR);
446 break;
447 case TOOL_ZOOMOUT:
448 // Set the mouse tool to "Zoom out"
449 mapPane.setWindowSelectionState(JMapPane.NONE);
450 mapPane.setState(JMapPane.ZOOM_OUT);
451 mapPane.setNormalCursor(SwingUtil.ZOOMOUT_CURSOR);
452 break;
453 default:
454 // Set map actions to default
455 mapPane.setWindowSelectionState(JMapPane.NONE);
456 mapPane.setState(JMapPane.NONE);
457 mapPane.setNormalCursor(null);
458 break;
459 }
460 mapPane.updateCursor();
461 }
462
463 /**
464 * @param id
465 * The ID of the Component to remove. The change will not be
466 * visible until {@link #initToolBar()} is called.
467 * @return <code>null</code> or the component that has been removed.
468 */
469 public JComponent removeId(int id) {
470 return toolAndActionButtons.remove(id);
471 }
472
473 /**
474 * Performs the action of an action button.
475 *
476 * @param tool
477 * the action
478 * @param e
479 * the event of the button
480 */
481 protected void performActionButton(int action, ActionEvent e) {
482 if (mapPane == null)
483 return;
484
485 // Perform the action "Zoom back": Revert the last zoom
486 if (action == ACTION_ZOOM_BACK) {
487 if (zoomBackIndex <= 1)
488 return;
489
490 zoomBackForwardButtonInAction = true;
491 zoomBackIndex--;
492 getButton(ACTION_ZOOM_FORWARD).setEnabled(true);
493 getButton(ACTION_ZOOM_BACK).setEnabled(zoomBackIndex > 1);
494
495 mapPane.setMapArea(lastZooms.get(zoomBackIndex - 1));
496 mapPane.refresh();
497 }
498
499 // Perform the action "Zoom forward": Re-do the last zoom
500 if (action == ACTION_ZOOM_FORWARD) {
501 if (zoomBackIndex < lastZooms.size()) {
502 zoomBackForwardButtonInAction = true;
503 zoomBackIndex++;
504 getButton(ACTION_ZOOM_BACK).setEnabled(true);
505 getButton(ACTION_ZOOM_FORWARD).setEnabled(
506 zoomBackIndex < lastZooms.size());
507
508 mapPane.setMapArea(lastZooms.get(zoomBackIndex - 1));
509 mapPane.refresh();
510 }
511 }
512 }
513
514 /**
515 * Adds a tool to the tool bar. Does nothing if a tool or action with the
516 * specified ID already exists!
517 *
518 * @param buttonAction
519 * action for the toggle button
520 * @param resetToolBar
521 * indicates whether the toolbar GUI is reset after adding the
522 * button (if adding several actions it useful only to reset the
523 * GUI for the last added tool)
524 */
525 public void addTool(MapPaneToolBarAction buttonAction, boolean resetToolBar) {
526 if (isButtonIDUsed(buttonAction.getID())) {
527 LOGGER
528 .warn("addTool(.) ignored because ID already used for tool or action: "
529 + buttonAction.getID());
530 return;
531 }
532 JToggleButton button = new JToggleButton(buttonAction);
533 button.setBorder(BorderFactory.createRaisedBevelBorder());
534 toolButtonGroup.add(button);
535 toolAndActionButtons.put(buttonAction.getID(), button);
536 if (resetToolBar)
537 initToolBar();
538 }
539
540 /**
541 * Adds a tool to the tool bar and resets the toolbar GUI.
542 *
543 * @param buttonAction
544 * action for the toggle button
545 */
546 public void addTool(MapPaneToolBarAction buttonAction) {
547 addTool(buttonAction, true);
548 }
549
550 /**
551 * Adds an action to the tool bar. Does nothing if a tool or action with the
552 * specified ID already exists!
553 *
554 * @param buttonAction
555 * action for the button
556 * @param resetToolBar
557 * indicates whether the toolbar GUI is reset after adding the
558 * button (if adding several actions it useful only to reset the
559 * GUI for the last added tool)
560 */
561 public void addAction(MapPaneToolBarAction buttonAction,
562 boolean resetToolBar) {
563 if (isButtonIDUsed(buttonAction.getID())) {
564 LOGGER
565 .warn("addAction(.) ignored because ID already used for tool or action: "
566 + buttonAction.getID());
567 return;
568 }
569 JButton button = new JButton(buttonAction);
570 button.setBorder(BorderFactory.createRaisedBevelBorder());
571 toolAndActionButtons.put(buttonAction.getID(), button);
572 if (resetToolBar)
573 initToolBar();
574 }
575
576 /**
577 * Adds any JComponent to the tool bar. Does nothing if a tool or action
578 * with the specified ID already exists!
579 *
580 * @param component
581 * A {@link JComponent} that shall be added
582 * @param id
583 * The ID associaded with the {@link JComponent}
584 * @param resetToolBar
585 * indicates whether the toolbar GUI is reset after adding the
586 * button (if adding several actions it useful only to reset the
587 * GUI for the last added tool)
588 */
589 public void addJComponent(JComponent component, int id, boolean resetToolBar) {
590
591 if (isButtonIDUsed(id)) {
592 LOGGER
593 .warn("addAction(.) ignored because ID already used for tool or action: "
594 + id);
595 return;
596 }
597
598 toolAndActionButtons.put(id, component);
599 if (resetToolBar)
600 initToolBar();
601 }
602
603 public void addSeparator(int id, Separator separator) {
604 if (isButtonIDUsed(id)) {
605 LOGGER
606 .warn("addSeparator(.) ignored because ID already used for tool or action. ");
607 return;
608 }
609 toolAndActionButtons.put(id, separator);
610 }
611
612 /**
613 * Adds an action to the tool bar and resets the toolbar GUI.
614 *
615 * @param buttonAction
616 * action for the toggle button
617 */
618 public void addAction(MapPaneToolBarAction buttonAction) {
619 addAction(buttonAction, true);
620 }
621
622 /**
623 * Returns the button for a specific tool or action.
624 *
625 * @param id
626 * the constant for any button in the {@link MapPaneToolBar}
627 * @return a {@link JButton} if {@code id} specifies an
628 * {@linkplain #getActionButton(int) action button} or
629 * {@link JToogleButton} if {@code id} specifies a
630 * {@linkplain #getToolButton(int) tool button}
631 */
632 public AbstractButton getButton(int id) {
633 AbstractButton button = (AbstractButton) toolAndActionButtons.get(id);
634 if (button == null)
635 LOGGER.warn("Unknown tool or action ID: " + id);
636 return button;
637 }
638
639 /**
640 * Returns the button for a specific tool.
641 *
642 * @param tool
643 * the constant for a tool
644 */
645 public JToggleButton getToolButton(int tool) {
646 AbstractButton button = getButton(tool);
647 if (button != null && !(button instanceof JToggleButton)) {
648 LOGGER.warn("ID specifies no tool: " + tool);
649 button = null;
650 }
651 return (JToggleButton) button;
652 }
653
654 /**
655 * Returns the button for a specific action.
656 *
657 * @param action
658 * the constant an action
659 */
660 public JButton getActionButton(int action) {
661 AbstractButton button = getButton(action);
662 if (button != null && !(button instanceof JButton)) {
663 LOGGER.warn("ID specifies no action: " + action);
664 button = null;
665 }
666 return (JButton) button;
667
668 }
669
670 /**
671 * Sets the selected tool.
672 *
673 * @param tool
674 * ID of the tool
675 */
676 public void setSelectedTool(Integer tool) {
677 if (tool == null)
678 toolButtonGroup.setUnselected();
679
680 JToggleButton button = getToolButton(tool);
681 if (button == null)
682 return;
683 button.setSelected(true);
684 button.getAction().actionPerformed(null);
685
686 selectedTool = tool;
687 }
688
689 /**
690 * Returns the selected tool.
691 *
692 * @return -1 if no tool is active
693 */
694 public int getSelectedTool() {
695 if (toolButtonGroup.getSelectedButton() == null)
696 return -1;
697 return selectedTool;
698 }
699
700 /**
701 * Sets whether a tool or action is activated or not. The visible property
702 * of the button is not affected.
703 *
704 * @param id
705 * tool or actionID
706 * @param enabled
707 * if {@code true} the tool becomes available
708 */
709 public void setButtonEnabled(int id, boolean enabled) {
710 AbstractButton button = getButton(id);
711 if (button == null)
712 return;
713 button.setEnabled(enabled);
714 }
715
716 /**
717 * Sets whether a tool or action is activated or not.
718 *
719 * @param id
720 * tool or actionID
721 * @param enabled
722 * if {@code true} the tool becomes available
723 * @param hideOnDisable
724 * if {@code true} the button is also hidden if {@code enabled}
725 * is {@code false}
726 */
727 public void setButtonEnabled(int id, boolean enabled, boolean hideOnDisable) {
728 AbstractButton button = getButton(id);
729 if (button == null)
730 return;
731 button.setEnabled(enabled);
732 // if button is enabled, it becomes visible anyway
733 // if button is disabled and the "hide" option is set, it is also hidden
734 if (enabled)
735 button.setVisible(true);
736 else
737 button.setVisible(!hideOnDisable);
738 }
739
740 /**
741 * Checks whether a ID is already used for a tool or action.
742 *
743 * @param tool
744 * tool ID
745 */
746 public boolean isButtonIDUsed(int id) {
747 return toolAndActionButtons.get(id) != null;
748 }
749
750 /**
751 * Checks whether a tool is activated.
752 *
753 * @param tool
754 * tool ID
755 * @return {@code false} if an unknown ID is specified
756 */
757 public boolean isButtonEnabled(int id) {
758 AbstractButton button = getButton(id);
759 if (button != null)
760 return button.isEnabled();
761 return false;
762 }
763
764 /**
765 * Sets the activation for all tools.
766 *
767 * @param enabled
768 * if {@code true} all tools becomes available
769 * @param hideOnDisable
770 * if {@code true} the buttons are also hidden if {@code enabled}
771 * is {@code false}
772 */
773 public void setAllToolsEnabled(boolean enabled, boolean hideOnDisable) {
774 for (int tool : toolAndActionButtons.keySet())
775 setButtonEnabled(tool, enabled, hideOnDisable);
776 }
777
778 /**
779 * Sets the activation for all actions.
780 *
781 * @param enabled
782 * if {@code true} all actions becomes available
783 * @param hideOnDisable
784 * if {@code true} the buttons are also hidden if {@code enabled}
785 * is {@code false}
786 */
787 public void setAllActionsEnabled(boolean enabled, boolean hideOnDisable) {
788 for (int id : toolAndActionButtons.keySet()) {
789 if (toolAndActionButtons.get(id) instanceof JButton) {
790 setButtonEnabled(id, enabled, hideOnDisable);
791 }
792 }
793
794 }
795
796 /**
797 * Returns the maximum ID of tools.
798 */
799 public int getMaxToolID() {
800 return toolAndActionButtons.lastKey();
801 }
802
803 /**
804 * Returns the minimum ID of tools.
805 */
806 public int getMinToolID() {
807 return toolAndActionButtons.firstKey();
808 }
809
810 /**
811 * Extends the {@link AbstractAction} with maintaining an ID and the
812 * {@link MapPaneToolBar} the actions controls. Additionally this class
813 * automatically calls
814 * {@link MapPaneToolBar#performToolButton(int, ActionEvent)} or
815 * {@link MapPaneToolBar#performActionButton(int, ActionEvent)} depending on
816 * whether the action is added via
817 * {@link MapPaneToolBar#addTool(MapPaneToolBarAction)} or
818 * {@link MapPaneToolBar#addAction(MapPaneToolBarAction)}.
819 *
820 * @author <a href="mailto:[email protected]">Martin Schmitz</a>
821 * (University of Bonn/Germany)
822 */
823 public static class MapPaneToolBarAction extends AbstractAction {
824 /** The ID of the action */
825 protected int id = -1;
826 /** The tool bar, this action is made for. */
827 protected MapPaneToolBar toolBar = null;
828
829 /**
830 * Creates a new action with a dummy description and no icon.
831 *
832 * @param id
833 * unique ID for the action
834 * @param toolBar
835 * toolbar this action is made for
836 */
837 public MapPaneToolBarAction(int id, MapPaneToolBar toolBar) {
838 this(id, toolBar, "" + id);
839 }
840
841 /**
842 * Creates a new action without an icon.
843 *
844 * @param id
845 * unique ID for the action
846 * @param toolBar
847 * toolbar this action is made for
848 * @param name
849 * description used for buttons or menus
850 */
851 public MapPaneToolBarAction(int id, MapPaneToolBar toolBar, String name) {
852 this(id, toolBar, name, null);
853 }
854
855 /**
856 * Creates a new action.
857 *
858 * @param id
859 * unique ID for the action
860 * @param toolBar
861 * toolbar this action is made for
862 * @param name
863 * description used for buttons or menus
864 * @param icon
865 * icon used for buttons or menus
866 */
867 public MapPaneToolBarAction(int id, MapPaneToolBar toolBar,
868 String name, Icon icon) {
869 this(id, toolBar, name, icon, null);
870 }
871
872 /**
873 * Creates a new action.
874 *
875 * @param id
876 * unique ID for the action
877 * @param toolBar
878 * The {@link MapPaneToolBar} this action is made for
879 * @param name
880 * description used for buttons or menus
881 * @param icon
882 * icon used for buttons or menus
883 * @param toolTip
884 * Tooltip to use for the button or menu
885 */
886 public MapPaneToolBarAction(int id, MapPaneToolBar toolBar,
887 String name, Icon icon, String toolTip) {
888 super(name, icon);
889
890 if (toolTip != null && !toolTip.trim().isEmpty()) {
891 putValue(Action.SHORT_DESCRIPTION, toolTip);
892 }
893
894 this.id = id;
895 this.toolBar = toolBar;
896 }
897
898 /**
899 * Calls {@link MapPaneToolBar#performToolButton(int, ActionEvent)} or
900 * {@link MapPaneToolBar#performActionButton(int, ActionEvent)}
901 * depending on whether the action is added to the toolbar via
902 * {@link MapPaneToolBar#addTool(MapPaneToolBarAction)} or
903 * {@link MapPaneToolBar#addAction(MapPaneToolBarAction)}.
904 */
905 public void actionPerformed(ActionEvent e) {
906 if (toolBar.toolAndActionButtons.get(id) instanceof JToggleButton)
907 toolBar.performToolButton(id, e);
908 else if (toolBar.toolAndActionButtons.get(id) instanceof JButton)
909 toolBar.performActionButton(id, e);
910 }
911
912 /**
913 * Returns the (unique) id of this action.
914 *
915 * @return
916 */
917 public int getID() {
918 return id;
919 }
920 }
921
922 /**
923 * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein Screenshot gemacht
924 * wird) wird. Dann werden wird der Hintergrund auf WEISS gesetzt.
925 *
926 * @author <a href="mailto:[email protected]">Stefan Alfons
927 * Kr&uuml;ger</a>
928 */
929 @Override
930 public void print(Graphics g) {
931 Color orig = getBackground();
932 setBackground(Color.WHITE);
933 // wrap in try/finally so that we always restore the state
934 try {
935 super.print(g);
936 } finally {
937 setBackground(orig);
938 }
939 }
940
941 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26