1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.commons.gui.shortcut;
21
22 import java.awt.BorderLayout;
23 import java.awt.Event;
24 import java.awt.FlowLayout;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.awt.event.FocusAdapter;
28 import java.awt.event.FocusEvent;
29 import java.awt.event.ItemEvent;
30 import java.awt.event.ItemListener;
31 import java.awt.event.KeyAdapter;
32 import java.awt.event.KeyEvent;
33 import javax.swing.AbstractAction;
34 import javax.swing.Action;
35 import javax.swing.JCheckBox;
36 import javax.swing.JPanel;
37 import javax.swing.JToggleButton;
38 import javax.swing.KeyStroke;
39 import javax.swing.event.ChangeEvent;
40 import javax.swing.event.ChangeListener;
41 import org.xnap.commons.gui.Builder;
42 import org.xnap.commons.i18n.I18n;
43 import org.xnap.commons.i18n.I18nFactory;
44
45 /***
46 * A panel to enter a keystroke.
47 *
48 * @author Steffen Pingel
49 */
50 public class KeyStrokePanel extends JPanel implements ActionListener {
51
52 private static I18n i18n = I18nFactory.getI18n(KeyStrokePanel.class);
53
54 public static String toString(KeyStroke stroke)
55 {
56 StringBuilder sb = new StringBuilder();
57
58 int m = stroke.getModifiers();
59 if ((m & Event.CTRL_MASK) != 0) {
60 sb.append(KeyEvent.getKeyModifiersText(Event.CTRL_MASK));
61 sb.append("+");
62 }
63 if ((m & Event.ALT_MASK) != 0) {
64 sb.append(KeyEvent.getKeyModifiersText(Event.ALT_MASK));
65 sb.append("+");
66 }
67 if ((m & Event.META_MASK) != 0) {
68 sb.append(KeyEvent.getKeyModifiersText(Event.META_MASK));
69 sb.append("+");
70 }
71 if ((m & Event.SHIFT_MASK) != 0) {
72 sb.append(KeyEvent.getKeyModifiersText(Event.SHIFT_MASK));
73 sb.append("+");
74 }
75 sb.append(KeyEvent.getKeyText(stroke.getKeyCode()));
76 return sb.toString();
77 }
78
79 private JCheckBox altCheckBox;
80 protected transient ChangeEvent changeEvent;
81 private JToggleButton charButton;
82 private JCheckBox ctrlCheckBox;
83 private KeyStroke defaultKeyStroke;
84 private int keyCode;
85 private CharButtonListener keyListener = new CharButtonListener();
86 private JCheckBox metaCheckBox;
87 private JCheckBox shiftCheckBox;
88 private DefaultAction defaultAction;
89 private NoneAction noneAction;
90
91 public KeyStrokePanel()
92 {
93 defaultAction = new DefaultAction();
94 noneAction = new NoneAction();
95
96 setLayout(new BorderLayout());
97
98
99 JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
100 add(topPanel, BorderLayout.NORTH);
101
102 ctrlCheckBox
103 = new JCheckBox(KeyEvent.getKeyModifiersText(Event.CTRL_MASK));
104 ctrlCheckBox.addActionListener(this);
105 topPanel.add(ctrlCheckBox);
106
107 altCheckBox
108 = new JCheckBox(KeyEvent.getKeyModifiersText(Event.ALT_MASK));
109 altCheckBox.addActionListener(this);
110 topPanel.add(altCheckBox);
111
112 metaCheckBox
113 = new JCheckBox(KeyEvent.getKeyModifiersText(Event.META_MASK));
114 metaCheckBox.addActionListener(this);
115 topPanel.add(metaCheckBox);
116
117 shiftCheckBox
118 = new JCheckBox(KeyEvent.getKeyModifiersText(Event.SHIFT_MASK));
119 shiftCheckBox.addActionListener(this);
120 topPanel.add(shiftCheckBox);
121
122 charButton = new JToggleButton(" ");
123 charButton.addItemListener(new ItemListener() {
124 public void itemStateChanged(ItemEvent event)
125 {
126 if (event.getStateChange() == ItemEvent.SELECTED) {
127
128 charButton.addKeyListener(keyListener);
129 }
130 else {
131 charButton.removeKeyListener(keyListener);
132 fireChangeEvent();
133 }
134 }
135 });
136 charButton.addFocusListener(new UntoggleListener());
137 topPanel.add(charButton);
138
139
140 JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
141 add(bottomPanel, BorderLayout.SOUTH);
142
143 bottomPanel.add(Builder.createButton(defaultAction));
144 bottomPanel.add(Builder.createButton(noneAction));
145 }
146
147 /***
148 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
149 */
150 public void actionPerformed(ActionEvent e)
151 {
152 fireChangeEvent();
153 }
154
155 public void addChangeListener(ChangeListener l)
156 {
157 listenerList.add(ChangeListener.class, l);
158 }
159
160 protected void fireChangeEvent() {
161 Object[] listeners = listenerList.getListenerList();
162
163 for (int i = listeners.length - 2; i >= 0; i -= 2) {
164 if (listeners[i] == ChangeListener.class) {
165
166 if (changeEvent == null) {
167 changeEvent = new ChangeEvent(this);
168 }
169 ((ChangeListener)listeners[i + 1]).stateChanged(changeEvent);
170 }
171 }
172 }
173
174 public KeyStroke getKeyStroke()
175 {
176 if (keyCode == KeyEvent.VK_UNDEFINED) {
177 return null;
178 }
179 else {
180 int m = 0;
181 m |= (ctrlCheckBox.isSelected()) ? Event.CTRL_MASK : 0;
182 m |= (altCheckBox.isSelected()) ? Event.ALT_MASK : 0;
183 m |= (metaCheckBox.isSelected()) ? Event.META_MASK : 0;
184 m |= (shiftCheckBox.isSelected()) ? Event.SHIFT_MASK : 0;
185 return KeyStroke.getKeyStroke(keyCode, m);
186 }
187 }
188
189 public void removeChangeListener(ChangeListener l)
190 {
191 listenerList.remove(ChangeListener.class, l);
192 }
193
194 @Override
195 public void setEnabled(boolean enabled)
196 {
197 super.setEnabled(enabled);
198
199 ctrlCheckBox.setEnabled(enabled);
200 altCheckBox.setEnabled(enabled);
201 metaCheckBox.setEnabled(enabled);
202 shiftCheckBox.setEnabled(enabled);
203 charButton.setEnabled(enabled);
204
205 defaultAction.setEnabled(enabled);
206 noneAction.setEnabled(enabled);
207 }
208
209 public void setDefaultKeyStroke(KeyStroke defaultKeyStroke)
210 {
211 this.defaultKeyStroke = defaultKeyStroke;
212 }
213
214 public void setKeyStroke(KeyStroke keyStroke)
215 {
216 if (keyStroke != null) {
217 int m = keyStroke.getModifiers();
218 ctrlCheckBox.setSelected((m & Event.CTRL_MASK) != 0);
219 altCheckBox.setSelected((m & Event.ALT_MASK) != 0);
220 metaCheckBox.setSelected((m & Event.META_MASK) != 0);
221 shiftCheckBox.setSelected((m & Event.SHIFT_MASK) != 0);
222 keyCode = keyStroke.getKeyCode();
223 charButton.setText(KeyEvent.getKeyText(keyCode));
224 }
225 else {
226 ctrlCheckBox.setSelected(false);
227 altCheckBox.setSelected(false);
228 metaCheckBox.setSelected(false);
229 shiftCheckBox.setSelected(false);
230 charButton.setText(" ");
231 keyCode = KeyEvent.VK_UNDEFINED;
232 }
233 }
234
235 private class CharButtonListener extends KeyAdapter {
236
237 public void keyPressed(KeyEvent e)
238 {
239 keyCode = e.getKeyCode();
240
241 charButton.setSelected(false);
242 charButton.setText(KeyEvent.getKeyText(keyCode));
243
244 }
245
246 }
247
248 /***
249 * Reperforms a search.
250 */
251 private class DefaultAction extends AbstractAction {
252
253 public DefaultAction()
254 {
255 putValue(Action.NAME, i18n.tr("Default"));
256 putValue(Action.SHORT_DESCRIPTION, i18n.tr("Reset to default"));
257 }
258
259 public void actionPerformed(ActionEvent event)
260 {
261 setKeyStroke(defaultKeyStroke);
262 fireChangeEvent();
263 }
264 }
265
266 /***
267 * Reperforms a search.
268 */
269 private class NoneAction extends AbstractAction {
270
271 public NoneAction()
272 {
273 putValue(Action.NAME, i18n.tr("None"));
274 putValue(Action.SHORT_DESCRIPTION,
275 i18n.tr("Assigns no keystroke"));
276 }
277
278 public void actionPerformed(ActionEvent event)
279 {
280 setKeyStroke(null);
281 fireChangeEvent();
282 }
283
284 }
285
286 private class UntoggleListener extends FocusAdapter {
287
288 public void focusLost(FocusEvent e)
289 {
290 charButton.setSelected(false);
291 }
292
293 }
294
295 }