source: josm/trunk/src/org/openstreetmap/josm/actions/ToggleAction.java@ 6429

Last change on this file since 6429 was 6338, checked in by Don-vip, 10 years ago

fix #9220 - fix toggle actions for good

File size: 6.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import java.awt.event.ActionEvent;
5import java.util.ArrayList;
6import java.util.List;
7
8import javax.swing.ButtonModel;
9import javax.swing.Icon;
10import javax.swing.JCheckBox;
11import javax.swing.JCheckBoxMenuItem;
12import javax.swing.JRadioButton;
13import javax.swing.JRadioButtonMenuItem;
14import javax.swing.JToggleButton;
15
16import org.openstreetmap.josm.Main;
17import org.openstreetmap.josm.tools.Shortcut;
18
19/**
20 * Abtract class for Toggle Actions.
21 * @since 6220
22 */
23public abstract class ToggleAction extends JosmAction {
24
25 private final List<ButtonModel> buttonModels = new ArrayList<ButtonModel>();
26
27 /**
28 * Constructs a {@code ToggleAction}.
29 *
30 * @param name the action's text as displayed on the menu (if it is added to a menu)
31 * @param icon the icon to use
32 * @param tooltip a longer description of the action that will be displayed in the tooltip. Please note
33 * that html is not supported for menu actions on some platforms.
34 * @param shortcut a ready-created shortcut object or null if you don't want a shortcut. But you always
35 * do want a shortcut, remember you can always register it with group=none, so you
36 * won't be assigned a shortcut unless the user configures one. If you pass null here,
37 * the user CANNOT configure a shortcut for your action.
38 * @param registerInToolbar register this action for the toolbar preferences?
39 * @param toolbarId identifier for the toolbar preferences. The iconName is used, if this parameter is null
40 * @param installAdapters false, if you don't want to install layer changed and selection changed adapters
41 */
42 public ToggleAction(String name, Icon icon, String tooltip, Shortcut shortcut, boolean registerInToolbar, String toolbarId, boolean installAdapters) {
43 super(name, icon, tooltip, shortcut, registerInToolbar, toolbarId, installAdapters);
44 // It is required to set the SELECTED_KEY to a non-null value in order to let Swing components update it
45 setSelected(false);
46 }
47
48 /**
49 * Constructs a {@code ToggleAction}.
50 *
51 * @param name the action's text as displayed on the menu (if it is added to a menu)
52 * @param iconName the name of icon to use
53 * @param tooltip a longer description of the action that will be displayed in the tooltip. Please note
54 * that html is not supported for menu actions on some platforms.
55 * @param shortcut a ready-created shortcut object or null if you don't want a shortcut. But you always
56 * do want a shortcut, remember you can always register it with group=none, so you
57 * won't be assigned a shortcut unless the user configures one. If you pass null here,
58 * the user CANNOT configure a shortcut for your action.
59 * @param registerInToolbar register this action for the toolbar preferences?
60 */
61 public ToggleAction(String name, String iconName, String tooltip, Shortcut shortcut, boolean registerInToolbar) {
62 super(name, iconName, tooltip, shortcut, registerInToolbar);
63 // It is required to set the SELECTED_KEY to a non-null value in order to let Swing components update it
64 setSelected(false);
65 }
66
67 protected final void setSelected(boolean selected) {
68 putValue(SELECTED_KEY, selected);
69 }
70
71 /**
72 * Determines if this action is currently being selected.
73 * @return {@code true} if this action is currently being selected, {@code false} otherwise
74 */
75 public final boolean isSelected() {
76 Object selected = getValue(SELECTED_KEY);
77 if (selected instanceof Boolean) {
78 return (Boolean) selected;
79 } else {
80 Main.warn(getClass().getName()+" does not define a boolean for SELECTED_KEY but "+selected+". You should report it to JOSM developers.");
81 return false;
82 }
83 }
84
85 /**
86 * Adds a button model
87 * @param model The button model to add
88 */
89 public final void addButtonModel(ButtonModel model) {
90 if (model != null && !buttonModels.contains(model)) {
91 buttonModels.add(model);
92 model.setSelected(isSelected());
93 }
94 }
95
96 /**
97 * Removes a button model
98 * @param model The button model to remove
99 */
100 public final void removeButtonModel(ButtonModel model) {
101 if (model != null && buttonModels.contains(model)) {
102 buttonModels.remove(model);
103 }
104 }
105
106 protected void notifySelectedState() {
107 boolean selected = isSelected();
108 for (ButtonModel model: buttonModels) {
109 if (model.isSelected() != selected) {
110 model.setSelected(selected);
111 }
112 }
113 }
114
115 /**
116 * Toggles the selcted action state, if needed according to the ActionEvent that trigerred the action.
117 * This method will do nothing if the action event comes from a Swing component supporting the SELECTED_KEY property because the component already set the selected state.
118 * This method needs to be called especially if the action is associated with a keyboard shortcut to ensure correct selected state.
119 * @see <a href="https://weblogs.java.net/blog/zixle/archive/2005/11/changes_to_acti.html">Changes to Actions in 1.6</a>
120 * @see <a href="http://docs.oracle.com/javase/6/docs/api/javax/swing/Action.html">Interface Action</a>
121 */
122 protected final void toggleSelectedState(ActionEvent e) {
123 if (e == null || !(e.getSource() instanceof JToggleButton ||
124 e.getSource() instanceof JCheckBox ||
125 e.getSource() instanceof JRadioButton ||
126 e.getSource() instanceof JCheckBoxMenuItem ||
127 e.getSource() instanceof JRadioButtonMenuItem
128 )) {
129 setSelected(!isSelected());
130 }
131 }
132}
Note: See TracBrowser for help on using the repository browser.