2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.form.editors;
45
import java.awt.event.*;
46
import java.beans.PropertyEditorSupport;
47
import java.lang.reflect.*;
51
import org.netbeans.modules.form.NamedPropertyEditor;
53
import org.openide.awt.Mnemonics;
54
import org.openide.explorer.propertysheet.editors.XMLPropertyEditor;
55
import org.openide.util.NbBundle;
57
public class KeyStrokeEditor extends PropertyEditorSupport
58
implements XMLPropertyEditor, NamedPropertyEditor {
59
private String TXT_CTRL;
60
private String TXT_ALT;
61
private String TXT_SHIFT;
63
public KeyStrokeEditor() {
64
ResourceBundle bundle =
65
org.openide.util.NbBundle.getBundle(KeyStrokeEditor.class);
66
TXT_CTRL = bundle.getString("CTL_CtrlAsText"); // NOI18N
67
TXT_SHIFT = bundle.getString("CTL_ShiftAsText"); // NOI18N
68
TXT_ALT = bundle.getString("CTL_AltAsText"); // NOI18N
71
public String getJavaInitializationString() {
72
KeyStroke key =(KeyStroke) getValue();
73
int mods = key.getModifiers();
74
StringBuffer modsText = new StringBuffer();
77
&(InputEvent.ALT_MASK | InputEvent.SHIFT_MASK | InputEvent.CTRL_MASK))) {
78
if (0 !=(mods & InputEvent.ALT_MASK))
79
modsText.append("java.awt.event.InputEvent.ALT_MASK"); // NOI18N
80
if (0 !=(mods & InputEvent.SHIFT_MASK)) {
81
if (modsText.length() > 0)
82
modsText.append(" | "); // NOI18N
83
modsText.append("java.awt.event.InputEvent.SHIFT_MASK"); // NOI18N
85
if (0 !=(mods & InputEvent.CTRL_MASK)) {
86
if (modsText.length() > 0)
87
modsText.append(" | "); // NOI18N
88
modsText.append("java.awt.event.InputEvent.CTRL_MASK"); // NOI18N
92
modsText.append("0"); // NOI18N
94
return "javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent." // NOI18N
95
+ getVirtualkeyName(key.getKeyCode()) + ", " + modsText.toString() + ")"; // NOI18N
98
public String getAsText() {
99
KeyStroke key = (KeyStroke) getValue();
100
return key != null ? keyStrokeAsString(key, true) : "null"; // NOI18N
103
public void setAsText(String text) throws IllegalArgumentException {
104
if (text == null || "".equals(text) || "null".equals(text)) { // NOI18N
109
KeyStroke key = keyStrokeFromString(text, true);
111
throw new IllegalArgumentException("Unrecognized key: " + text); // NOI18N
116
private static String getVirtualkeyName(int keycode) {
117
Field[] fields = KeyEvent.class.getDeclaredFields();
118
for (int i = 0; i < fields.length; i++) {
120
int modifiers = f.getModifiers();
121
if (Modifier.isPublic(modifiers)
122
&& Modifier.isStatic(modifiers)
123
&& Modifier.isFinal(modifiers)
124
&& f.getType() == Integer.TYPE
125
&& f.getName().startsWith("VK_")) { // NOI18N
127
if (f.getInt(KeyEvent.class) == keycode) {
131
catch (IllegalAccessException ex) {
132
ex.printStackTrace(); // should not happen
139
private KeyStroke keyStrokeFromString(String s, boolean i18ned) {
140
StringTokenizer st = new StringTokenizer(s, "+"); // NOI18N
145
String alt = i18ned ? TXT_ALT : "Alt"; // NOI18N
146
String shift = i18ned ? TXT_SHIFT : "Shift"; // NOI18N
147
String ctrl = i18ned ? TXT_CTRL : "Ctrl"; // NOI18N
149
while (st.hasMoreTokens() &&(token = st.nextToken()) != null) {
150
if (alt.equalsIgnoreCase(token))
151
mods |= InputEvent.ALT_MASK;
152
else if (shift.equalsIgnoreCase(token))
153
mods |= InputEvent.SHIFT_MASK;
154
else if (ctrl.equalsIgnoreCase(token))
155
mods |= InputEvent.CTRL_MASK;
157
String keycodeName = "VK_" + token.toUpperCase(); // NOI18N
159
keycode = KeyEvent.class.getField(keycodeName).getInt(KeyEvent.class);
161
catch (Exception e) {
167
return KeyStroke.getKeyStroke(keycode, mods);
172
private String keyStrokeAsString(KeyStroke key, boolean i18ned) {
173
String alt = i18ned ? TXT_ALT : "Alt"; // NOI18N
174
String shift = i18ned ? TXT_SHIFT : "Shift"; // NOI18N
175
String ctrl = i18ned ? TXT_CTRL : "Ctrl"; // NOI18N
177
StringBuffer buf = new StringBuffer();
178
int mods = key.getModifiers();
179
int modMasks[] = { InputEvent.SHIFT_MASK, InputEvent.CTRL_MASK,
180
InputEvent.ALT_MASK, };
181
String modMaskStrings[] = { shift, ctrl, alt, };
183
for (int i = 0; i < modMasks.length; i++) {
184
if ((mods & modMasks[i]) != 0) {
185
buf.append(modMaskStrings[i]);
186
buf.append("+"); // NOI18N
189
String keyName = getVirtualkeyName(key.getKeyCode());
190
if (keyName != null) {
191
buf.append(keyName.substring(3));
193
return buf.toString();
200
public static final String XML_KEYSTROKE = "KeyStroke"; // NOI18N
201
public static final String ATTR_KEY = "key"; // NOI18N
203
public void readFromXML(org.w3c.dom.Node element) throws java.io.IOException {
204
if (!XML_KEYSTROKE.equals(element.getNodeName())) {
205
throw new java.io.IOException();
207
org.w3c.dom.NamedNodeMap attributes = element.getAttributes();
209
String value = attributes.getNamedItem(ATTR_KEY).getNodeValue();
210
KeyStroke key = keyStrokeFromString(value, false);
212
throw new IllegalArgumentException();
216
catch (Exception e) {
217
throw new java.io.IOException();
221
public org.w3c.dom.Node storeToXML(org.w3c.dom.Document doc) {
222
KeyStroke key = (KeyStroke) getValue();
223
String str = key != null ? keyStrokeAsString(key, false) : "null"; // NOI18N
225
org.w3c.dom.Element el = doc.createElement(XML_KEYSTROKE);
226
el.setAttribute(ATTR_KEY, str);
234
public boolean supportsCustomEditor() {
238
public java.awt.Component getCustomEditor() {
239
return new CustomEditor();
242
// NamedPropertyEditor implementation
243
public String getDisplayName() {
244
return NbBundle.getBundle(getClass()).getString("CTL_KeyStrokeEditor_DisplayName"); // NOI18N
247
private static String[] _virtualKeys;
249
private class CustomEditor extends JPanel
251
private KeyGrabberField _keyGrabber;
252
private JCheckBox _ctrl, _alt, _shift;
253
private JComboBox _virtualKey;
256
setLayout(new GridBagLayout());
258
ResourceBundle bundle =
259
org.openide.util.NbBundle.getBundle(KeyStrokeEditor.class);
261
JLabel virtualKeyLabel = new JLabel();
262
Mnemonics.setLocalizedText(virtualKeyLabel, bundle.getString("CTL_VirtualKey")); // NOI18N
264
GridBagConstraints gbc = new GridBagConstraints();
268
gbc.anchor = gbc.WEST;
272
gbc.insets = new Insets(12, 12, 5, 12);
273
add(virtualKeyLabel, gbc);
275
gbc = new GridBagConstraints();
279
gbc.fill = gbc.HORIZONTAL;
282
gbc.insets = new Insets(12, 0, 5, 11);
283
add(_virtualKey = new JComboBox(), gbc);
284
_virtualKey.getAccessibleContext().setAccessibleDescription(
285
bundle.getString("ACSD_VirtualKey")); // NOI18N
287
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 0));
288
_ctrl = new JCheckBox();
289
Mnemonics.setLocalizedText(_ctrl, bundle.getString("CTL_Ctrl")); // NOI18N
290
_ctrl.getAccessibleContext().setAccessibleDescription(
291
bundle.getString("ACSD_CtrlKey")); // NOI18N
293
_alt = new JCheckBox();
294
Mnemonics.setLocalizedText(_alt, bundle.getString("CTL_Alt")); // NOI18N
295
_alt.getAccessibleContext().setAccessibleDescription(
296
bundle.getString("ACSD_AltKey")); // NOI18N
298
_shift = new JCheckBox();
299
Mnemonics.setLocalizedText(_shift, bundle.getString("CTL_Shift")); // NOI18N
300
_shift.getAccessibleContext().setAccessibleDescription(
301
bundle.getString("ACSD_ShiftKey")); // NOI18N
303
virtualKeyLabel.setLabelFor(_virtualKey);
305
gbc = new GridBagConstraints();
312
gbc.insets = new Insets(12, 0, 5, 12);
315
JLabel keyStrokeLabel = new JLabel();
316
Mnemonics.setLocalizedText(keyStrokeLabel, bundle.getString("CTL_KeyStroke")); // NOI18N
318
gbc = new GridBagConstraints();
322
gbc.anchor = gbc.WEST;
326
gbc.insets = new Insets(0, 12, 0, 12);
327
add(keyStrokeLabel, gbc);
329
gbc = new GridBagConstraints();
333
gbc.fill = gbc.HORIZONTAL;
336
gbc.insets = new Insets(0, 0, 0, 11);
337
add(_keyGrabber = new KeyGrabberField(), gbc);
338
_keyGrabber.getAccessibleContext().setAccessibleDescription(
339
bundle.getString("ACSD_KeyStroke")); // NOI18N
340
keyStrokeLabel.setLabelFor(_keyGrabber);
342
_keyGrabber.addActionListener(new ActionListener() {
343
public void actionPerformed(ActionEvent ev) {
344
setAsText(_keyGrabber.getText());
348
getAccessibleContext().setAccessibleDescription(
349
bundle.getString("ACSD_KeyStrokeCustomEditor")); // NOI18N
351
// fill in virtual key list
353
if (_virtualKeys == null) {
354
java.util.List list = new ArrayList();
356
Field[] fields = KeyEvent.class.getDeclaredFields();
357
for (int i = 0; i < fields.length; i++) {
359
int modifiers = f.getModifiers();
360
if (Modifier.isPublic(modifiers)
361
&& Modifier.isStatic(modifiers)
362
&& Modifier.isFinal(modifiers)
363
&& f.getType() == Integer.TYPE
364
&& f.getName().startsWith("VK_")) { // NOI18N
365
list.add(f.getName());
368
_virtualKeys = new String[list.size()];
369
for (int i = 0; i < list.size(); i++) {
370
_virtualKeys[i] =(String) list.get(i);
373
_virtualKey.addItem(""); // NOI18N
374
for (int i = 0; i < _virtualKeys.length; i++)
375
_virtualKey.addItem(_virtualKeys[i]);
377
KeyStroke key =(KeyStroke) getValue();
383
ItemListener il = new ItemListener() {
384
public void itemStateChanged(ItemEvent e) {
388
_virtualKey.addItemListener(il);
389
_ctrl.addItemListener(il);
390
_alt.addItemListener(il);
391
_shift.addItemListener(il);
394
java.awt.Component getKeyGrabber() {
398
private void setKeyStroke(KeyStroke key) {
399
_ctrl.setSelected(0 !=(InputEvent.CTRL_MASK & key.getModifiers()));
400
_alt.setSelected(0 !=(InputEvent.ALT_MASK & key.getModifiers()));
401
_shift.setSelected(0 !=(InputEvent.SHIFT_MASK & key.getModifiers()));
403
int keycode = key.getKeyCode();
404
String keyName = getVirtualkeyName(keycode);
405
if (keyName != null) {
406
_virtualKey.setSelectedItem(keyName);
407
_keyGrabber.setText(getAsText());
411
private void virtualKeyChanged() {
412
String keyName =(String) _virtualKey.getSelectedItem();
413
if ("".equals(keyName)) { // NOI18N
414
_keyGrabber.setText(""); // NOI18N
420
Field f = KeyEvent.class.getDeclaredField(keyName);
421
int keycode = f.getInt(KeyEvent.class);
423
if (_ctrl.isSelected())
424
mods |= InputEvent.CTRL_MASK;
425
if (_shift.isSelected())
426
mods |= InputEvent.SHIFT_MASK;
427
if (_alt.isSelected())
428
mods |= InputEvent.ALT_MASK;
430
setValue(KeyStroke.getKeyStroke(keycode, mods));
431
_keyGrabber.setText(getAsText());
433
catch (NoSuchFieldException ex) {
434
ex.printStackTrace(); // should not happen
436
catch (IllegalAccessException ex) {
437
ex.printStackTrace(); // should not happen
441
private class KeyGrabberField extends JTextField {
442
protected void processKeyEvent(KeyEvent e) {
443
if (e.getKeyCode() == KeyEvent.VK_TAB)
444
super.processKeyEvent(e);
445
else if (e.getID() == KeyEvent.KEY_PRESSED) {
446
int keycode = e.getKeyCode();
447
if (keycode != KeyEvent.VK_CONTROL
448
&& keycode != KeyEvent.VK_ALT
449
&& keycode != KeyEvent.VK_SHIFT) {
450
KeyStroke key = KeyStroke.getKeyStroke(keycode, e.getModifiers());