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

Last change on this file since 12060 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
RevLine 
[4840]1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
[4843]6import java.awt.Component;
[4840]7import java.awt.event.ActionEvent;
8
9import org.openstreetmap.josm.Main;
[11224]10import org.openstreetmap.josm.data.preferences.BooleanProperty;
11import org.openstreetmap.josm.tools.ListenerList;
[4840]12
[6220]13/**
14 * This action toggles the Expert mode.
15 * @since 4840
16 */
17public class ExpertToggleAction extends ToggleAction {
[4840]18
[11224]19 /**
20 * This listener is notified whenever the expert mode setting changed.
21 */
[10600]22 @FunctionalInterface
[4840]23 public interface ExpertModeChangeListener {
[11224]24 /**
25 * The expert mode changed.
26 * @param isExpert <code>true</code> if expert mode was enabled, false otherwise.
27 */
[4840]28 void expertChanged(boolean isExpert);
29 }
30
[11224]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();
[4840]34
[11224]35 private static final BooleanProperty PREF_EXPERT = new BooleanProperty("expert", false);
36
[6792]37 private static final ExpertToggleAction INSTANCE = new ExpertToggleAction();
[4843]38
[6889]39 private static synchronized void fireExpertModeChanged(boolean isExpert) {
[11224]40 listeners.fireEvent(listener -> listener.expertChanged(isExpert));
41 visibilityToggleListeners.fireEvent(c -> c.setVisible(isExpert));
[4840]42 }
43
44 /**
[4841]45 * Register a expert mode change listener
[4840]46 *
47 * @param listener the listener. Ignored if null.
48 */
49 public static void addExpertModeChangeListener(ExpertModeChangeListener listener) {
50 addExpertModeChangeListener(listener, false);
51 }
52
[6889]53 public static synchronized void addExpertModeChangeListener(ExpertModeChangeListener listener, boolean fireWhenAdding) {
[4840]54 if (listener == null) return;
[11224]55 listeners.addWeakListener(listener);
[4840]56 if (fireWhenAdding) {
[4843]57 listener.expertChanged(isExpert());
[4840]58 }
59 }
60
61 /**
[4841]62 * Removes a expert mode change listener
[4840]63 *
64 * @param listener the listener. Ignored if null.
65 */
[6889]66 public static synchronized void removeExpertModeChangeListener(ExpertModeChangeListener listener) {
[4840]67 if (listener == null) return;
[11224]68 listeners.removeListener(listener);
[4840]69 }
70
[11224]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 */
[6889]75 public static synchronized void addVisibilitySwitcher(Component c) {
[4843]76 if (c == null) return;
[11224]77 visibilityToggleListeners.addWeakListener(c);
[4843]78 c.setVisible(isExpert());
79 }
80
[11224]81 /**
82 * Stops tracking visibility changes for the given component.
83 * @param c The component.
84 * @see #addVisibilitySwitcher(Component)
85 */
[6889]86 public static synchronized void removeVisibilitySwitcher(Component c) {
[4843]87 if (c == null) return;
[11224]88 visibilityToggleListeners.removeListener(c);
[4843]89 }
90
[6220]91 /**
92 * Constructs a new {@code ExpertToggleAction}.
93 */
[4840]94 public ExpertToggleAction() {
[6220]95 super(tr("Expert Mode"),
96 "expert",
97 tr("Enable/disable expert mode"),
98 null,
99 false /* register toolbar */
[4840]100 );
101 putValue("toolbar", "expertmode");
[9611]102 if (Main.toolbar != null) {
103 Main.toolbar.register(this);
104 }
[11224]105 setSelected(PREF_EXPERT.get());
[4840]106 notifySelectedState();
107 }
108
[6792]109 @Override
[6890]110 protected final void notifySelectedState() {
[6220]111 super.notifySelectedState();
[11224]112 PREF_EXPERT.put(isSelected());
[6220]113 fireExpertModeChanged(isSelected());
[4840]114 }
115
[11224]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
[6084]128 @Override
[4840]129 public void actionPerformed(ActionEvent e) {
[6327]130 toggleSelectedState(e);
[6220]131 notifySelectedState();
[4840]132 }
133
[6220]134 /**
135 * Replies the unique instance of this action.
136 * @return The unique instance of this action
137 */
[4843]138 public static ExpertToggleAction getInstance() {
139 return INSTANCE;
140 }
141
[6220]142 /**
143 * Determines if expert mode is enabled.
144 * @return {@code true} if expert mode is enabled, {@code false} otherwise.
145 */
[4843]146 public static boolean isExpert() {
147 return INSTANCE.isSelected();
148 }
[4840]149}
Note: See TracBrowser for help on using the repository browser.