source: josm/trunk/src/org/openstreetmap/josm/actions/ExpertToggleAction.java@ 12346

Last change on this file since 12346 was 11224, checked in by michael2402, 7 years ago

Simplify ExpertToggleAction

Make ExpertToggleAction use the listener list to track weak listeners and add a method to set expert mode explicitly. Use it in OsmDataLayerTest to make tracing expert mode problems easier.

Add test case for ExpertToggleAction.

  • Property svn:eol-style set to native
File size: 4.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Component;
7import java.awt.event.ActionEvent;
8
9import org.openstreetmap.josm.Main;
10import org.openstreetmap.josm.data.preferences.BooleanProperty;
11import org.openstreetmap.josm.tools.ListenerList;
12
13/**
14 * This action toggles the Expert mode.
15 * @since 4840
16 */
17public class ExpertToggleAction extends ToggleAction {
18
19 /**
20 * This listener is notified whenever the expert mode setting changed.
21 */
22 @FunctionalInterface
23 public interface ExpertModeChangeListener {
24 /**
25 * The expert mode changed.
26 * @param isExpert <code>true</code> if expert mode was enabled, false otherwise.
27 */
28 void expertChanged(boolean isExpert);
29 }
30
31 // TODO: Switch to checked list. We can do this as soon as we do not see any more warnings.
32 private static final ListenerList<ExpertModeChangeListener> listeners = ListenerList.createUnchecked();
33 private static final ListenerList<Component> visibilityToggleListeners = ListenerList.createUnchecked();
34
35 private static final BooleanProperty PREF_EXPERT = new BooleanProperty("expert", false);
36
37 private static final ExpertToggleAction INSTANCE = new ExpertToggleAction();
38
39 private static synchronized void fireExpertModeChanged(boolean isExpert) {
40 listeners.fireEvent(listener -> listener.expertChanged(isExpert));
41 visibilityToggleListeners.fireEvent(c -> c.setVisible(isExpert));
42 }
43
44 /**
45 * Register a expert mode change listener
46 *
47 * @param listener the listener. Ignored if null.
48 */
49 public static void addExpertModeChangeListener(ExpertModeChangeListener listener) {
50 addExpertModeChangeListener(listener, false);
51 }
52
53 public static synchronized void addExpertModeChangeListener(ExpertModeChangeListener listener, boolean fireWhenAdding) {
54 if (listener == null) return;
55 listeners.addWeakListener(listener);
56 if (fireWhenAdding) {
57 listener.expertChanged(isExpert());
58 }
59 }
60
61 /**
62 * Removes a expert mode change listener
63 *
64 * @param listener the listener. Ignored if null.
65 */
66 public static synchronized void removeExpertModeChangeListener(ExpertModeChangeListener listener) {
67 if (listener == null) return;
68 listeners.removeListener(listener);
69 }
70
71 /**
72 * Marks a component to be only visible when expert mode is enabled. The visibility of the component is changed automatically.
73 * @param c The component.
74 */
75 public static synchronized void addVisibilitySwitcher(Component c) {
76 if (c == null) return;
77 visibilityToggleListeners.addWeakListener(c);
78 c.setVisible(isExpert());
79 }
80
81 /**
82 * Stops tracking visibility changes for the given component.
83 * @param c The component.
84 * @see #addVisibilitySwitcher(Component)
85 */
86 public static synchronized void removeVisibilitySwitcher(Component c) {
87 if (c == null) return;
88 visibilityToggleListeners.removeListener(c);
89 }
90
91 /**
92 * Constructs a new {@code ExpertToggleAction}.
93 */
94 public ExpertToggleAction() {
95 super(tr("Expert Mode"),
96 "expert",
97 tr("Enable/disable expert mode"),
98 null,
99 false /* register toolbar */
100 );
101 putValue("toolbar", "expertmode");
102 if (Main.toolbar != null) {
103 Main.toolbar.register(this);
104 }
105 setSelected(PREF_EXPERT.get());
106 notifySelectedState();
107 }
108
109 @Override
110 protected final void notifySelectedState() {
111 super.notifySelectedState();
112 PREF_EXPERT.put(isSelected());
113 fireExpertModeChanged(isSelected());
114 }
115
116 /**
117 * Forces the expert mode state to the given state.
118 * @param isExpert if expert mode should be used.
119 * @since 11224
120 */
121 public void setExpert(boolean isExpert) {
122 if (isSelected() != isExpert) {
123 setSelected(isExpert);
124 notifySelectedState();
125 }
126 }
127
128 @Override
129 public void actionPerformed(ActionEvent e) {
130 toggleSelectedState(e);
131 notifySelectedState();
132 }
133
134 /**
135 * Replies the unique instance of this action.
136 * @return The unique instance of this action
137 */
138 public static ExpertToggleAction getInstance() {
139 return INSTANCE;
140 }
141
142 /**
143 * Determines if expert mode is enabled.
144 * @return {@code true} if expert mode is enabled, {@code false} otherwise.
145 */
146 public static boolean isExpert() {
147 return INSTANCE.isSelected();
148 }
149}
Note: See TracBrowser for help on using the repository browser.