source: josm/trunk/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedTextField.java@ 7005

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

see #8465 - use diamond operator where applicable

File size: 7.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.widgets;
3
4import java.awt.event.FocusEvent;
5import java.awt.event.FocusListener;
6import java.awt.event.KeyEvent;
7import java.util.ArrayList;
8import java.util.HashSet;
9import java.util.List;
10import java.util.Set;
11
12import javax.swing.Action;
13import javax.swing.JMenu;
14import javax.swing.JMenuItem;
15import javax.swing.KeyStroke;
16import javax.swing.text.Document;
17
18import org.openstreetmap.josm.Main;
19import org.openstreetmap.josm.actions.JosmAction;
20import org.openstreetmap.josm.tools.Pair;
21import org.openstreetmap.josm.tools.Shortcut;
22
23/**
24 * A JTextField that disabled all JOSM shortcuts composed of a single key without modifier (except F1 to F12),
25 * in order to avoid them to be triggered while typing.
26 * This allows to include text fields in toggle dialogs (needed for relation filter).
27 * @since 5696
28 */
29public class DisableShortcutsOnFocusGainedTextField extends JosmTextField implements FocusListener {
30
31 /**
32 * Constructs a new <code>TextField</code>. A default model is created,
33 * the initial string is <code>null</code>,
34 * and the number of columns is set to 0.
35 */
36 public DisableShortcutsOnFocusGainedTextField() {
37 init();
38 }
39
40 /**
41 * Constructs a new <code>TextField</code> initialized with the
42 * specified text. A default model is created and the number of
43 * columns is 0.
44 *
45 * @param text the text to be displayed, or <code>null</code>
46 */
47 public DisableShortcutsOnFocusGainedTextField(String text) {
48 super(text);
49 init();
50 }
51
52 /**
53 * Constructs a new empty <code>TextField</code> with the specified
54 * number of columns.
55 * A default model is created and the initial string is set to
56 * <code>null</code>.
57 *
58 * @param columns the number of columns to use to calculate
59 * the preferred width; if columns is set to zero, the
60 * preferred width will be whatever naturally results from
61 * the component implementation
62 */
63 public DisableShortcutsOnFocusGainedTextField(int columns) {
64 super(columns);
65 init();
66 }
67
68 /**
69 * Constructs a new <code>TextField</code> initialized with the
70 * specified text and columns. A default model is created.
71 *
72 * @param text the text to be displayed, or <code>null</code>
73 * @param columns the number of columns to use to calculate
74 * the preferred width; if columns is set to zero, the
75 * preferred width will be whatever naturally results from
76 * the component implementation
77 */
78 public DisableShortcutsOnFocusGainedTextField(String text, int columns) {
79 super(text, columns);
80 init();
81 }
82
83 /**
84 * Constructs a new <code>JTextField</code> that uses the given text
85 * storage model and the given number of columns.
86 * This is the constructor through which the other constructors feed.
87 * If the document is <code>null</code>, a default model is created.
88 *
89 * @param doc the text storage to use; if this is <code>null</code>,
90 * a default will be provided by calling the
91 * <code>createDefaultModel</code> method
92 * @param text the initial string to display, or <code>null</code>
93 * @param columns the number of columns to use to calculate
94 * the preferred width &gt;= 0; if <code>columns</code>
95 * is set to zero, the preferred width will be whatever
96 * naturally results from the component implementation
97 * @exception IllegalArgumentException if <code>columns</code> &lt; 0
98 */
99 public DisableShortcutsOnFocusGainedTextField(Document doc, String text, int columns) {
100 super(doc, text, columns);
101 init();
102 }
103
104 private final List<Pair<Action,Shortcut>> unregisteredActionShortcuts = new ArrayList<>();
105 private final Set<JosmAction> disabledMenuActions = new HashSet<>();
106
107 protected final void init() {
108 addFocusListener(this);
109 }
110
111 @Override
112 public void focusGained(FocusEvent e) {
113 disableMenuActions();
114 unregisterActionShortcuts();
115 }
116
117 @Override
118 public void focusLost(FocusEvent e) {
119 restoreActionShortcuts();
120 restoreMenuActions();
121 }
122
123 /**
124 * Disables all relevant menu actions.
125 * @see #hasToBeDisabled
126 */
127 protected void disableMenuActions() {
128 disabledMenuActions.clear();
129 for (int i = 0; i < Main.main.menu.getMenuCount(); i++) {
130 JMenu menu = Main.main.menu.getMenu(i);
131 if (menu != null) {
132 for (int j = 0; j < menu.getItemCount(); j++) {
133 JMenuItem item = menu.getItem(j);
134 if (item != null) {
135 Action action = item.getAction();
136 if (action instanceof JosmAction && action.isEnabled()) {
137 Shortcut shortcut = ((JosmAction) action).getShortcut();
138 if (shortcut != null) {
139 KeyStroke ks = shortcut.getKeyStroke();
140 if (hasToBeDisabled(ks)) {
141 action.setEnabled(false);
142 disabledMenuActions.add((JosmAction) action);
143 }
144 }
145 }
146 }
147 }
148 }
149 }
150 }
151
152 /**
153 * Unregisters all relevant action shortcuts.
154 * @see #hasToBeDisabled
155 */
156 protected void unregisterActionShortcuts() {
157 unregisteredActionShortcuts.clear();
158 // Unregister all actions without modifiers to avoid them to be triggered by typing in this text field
159 for (Shortcut shortcut : Shortcut.listAll()) {
160 KeyStroke ks = shortcut.getKeyStroke();
161 if (hasToBeDisabled(ks)) {
162 Action action = Main.getRegisteredActionShortcut(shortcut);
163 if (action != null) {
164 Main.unregisterActionShortcut(action, shortcut);
165 unregisteredActionShortcuts.add(new Pair<>(action,shortcut));
166 }
167 }
168 }
169 }
170
171 /**
172 * Returns true if the given shortcut has no modifier and is not an actions key.
173 * @see KeyEvent#isActionKey()
174 */
175 protected boolean hasToBeDisabled(KeyStroke ks) {
176 return ks != null && ks.getModifiers() == 0 && !new KeyEvent(
177 this, KeyEvent.KEY_PRESSED, 0, ks.getModifiers(), ks.getKeyCode(), ks.getKeyChar()).isActionKey();
178 }
179
180 /**
181 * Restore all actions previously disabled
182 */
183 protected void restoreMenuActions() {
184 for (JosmAction a : disabledMenuActions) {
185 a.setEnabled(true);
186 }
187 disabledMenuActions.clear();
188 }
189
190 /**
191 * Restore all action shortcuts previously unregistered
192 */
193 protected void restoreActionShortcuts() {
194 for (Pair<Action,Shortcut> p : unregisteredActionShortcuts) {
195 Main.registerActionShortcut(p.a, p.b);
196 }
197 unregisteredActionShortcuts.clear();
198 }
199}
Note: See TracBrowser for help on using the repository browser.