001: /*
002: * ShortcutsDialog1.java
003: *
004: * Created on February 20, 2006, 2:51 PM
005: */
006:
007: package org.netbeans.modules.options.keymap;
008:
009: import java.awt.AWTKeyStroke;
010: import java.awt.Color;
011: import java.awt.Component;
012: import java.awt.KeyboardFocusManager;
013: import java.awt.event.ActionEvent;
014: import java.awt.event.ActionListener;
015: import java.awt.event.KeyEvent;
016: import java.awt.event.KeyListener;
017: import java.text.MessageFormat;
018: import java.util.Collections;
019: import javax.swing.AbstractButton;
020: import javax.swing.JButton;
021: import javax.swing.JLabel;
022: import javax.swing.KeyStroke;
023: import org.netbeans.core.options.keymap.api.ShortcutAction;
024: import org.netbeans.core.options.keymap.api.ShortcutsFinder;
025: import org.openide.awt.Mnemonics;
026: import org.openide.util.NbBundle;
027:
028: /**
029: *
030: * @author Jan Jancura
031: */
032: public class ShortcutsDialog extends javax.swing.JPanel {
033: public static final String PROP_SHORTCUT_VALID = "ShortcutsDialog.PROP_SHORTCUT_VALID"; //NOI18N
034:
035: private Listener listener = null;
036: private JButton bTab = new JButton();
037: private JButton bClear = new JButton();
038: private ShortcutsFinder f = null;
039: private boolean shortcutValid = false;
040:
041: void init(ShortcutsFinder f) {
042: this .f = f;
043: loc(lShortcut, "Shortcut"); //NOI18N
044: lConflict.setForeground(Color.red);
045: loc(bTab, "CTL_Tab"); //NOI18N
046: bTab.getAccessibleContext().setAccessibleName(loc("AN_Tab")); //NOI18N
047: bTab.getAccessibleContext().setAccessibleDescription(
048: loc("AD_Tab")); //NOI18N
049: loc(bClear, "CTL_Clear"); //NOI18N
050: bClear.getAccessibleContext()
051: .setAccessibleName(loc("AN_Clear")); //NOI18N
052: bClear.getAccessibleContext().setAccessibleDescription(
053: loc("AD_Clear")); //NOI18N
054: tfShortcut.setFocusTraversalKeys(
055: KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
056: Collections.<AWTKeyStroke> emptySet());
057: tfShortcut.setFocusTraversalKeys(
058: KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS,
059: Collections.<AWTKeyStroke> emptySet());
060: tfShortcut.getAccessibleContext().setAccessibleName(
061: loc("AN_Shortcut")); //NOI18N
062: tfShortcut.getAccessibleContext().setAccessibleDescription(
063: loc("AD_Shortcut")); //NOI18N
064: // tfShortcut.setFocusTraversalKeys (
065: // KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
066: // Collections.EMPTY_SET
067: // );
068: tfShortcut.setFocusTraversalKeys(
069: KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
070: Collections.<AWTKeyStroke> emptySet());
071: listener = new Listener();
072: tfShortcut.addKeyListener(listener);
073: }
074:
075: private static String loc(String key) {
076: return NbBundle.getMessage(ShortcutsDialog.class, key);
077: }
078:
079: private static void loc(Component c, String key) {
080: if (c instanceof AbstractButton)
081: Mnemonics.setLocalizedText((AbstractButton) c, loc(key));
082: else
083: Mnemonics.setLocalizedText((JLabel) c, loc(key));
084: }
085:
086: /** Creates new form ShortcutsDialog1 */
087: public ShortcutsDialog() {
088: initComponents();
089: }
090:
091: Listener getListener() {
092: return listener;
093: }
094:
095: public javax.swing.JLabel getLShortcut() {
096: return lShortcut;
097: }
098:
099: public javax.swing.JTextField getTfShortcut() {
100: return tfShortcut;
101: }
102:
103: /** This method is called from within the constructor to
104: * initialize the form.
105: * WARNING: Do NOT modify this code. The content of this method is
106: * always regenerated by the Form Editor.
107: */
108: // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
109: private void initComponents() {
110:
111: lShortcut = new javax.swing.JLabel();
112: tfShortcut = new javax.swing.JTextField();
113: lConflict = new javax.swing.JLabel();
114:
115: lShortcut.setLabelFor(tfShortcut);
116: lShortcut.setText("Shortcut:");
117:
118: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
119: this );
120: this .setLayout(layout);
121: layout
122: .setHorizontalGroup(layout
123: .createParallelGroup(
124: org.jdesktop.layout.GroupLayout.LEADING)
125: .add(
126: layout
127: .createSequentialGroup()
128: .addContainerGap()
129: .add(
130: layout
131: .createParallelGroup(
132: org.jdesktop.layout.GroupLayout.LEADING)
133: .add(
134: lConflict,
135: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
136: 477,
137: Short.MAX_VALUE)
138: .add(
139: layout
140: .createSequentialGroup()
141: .add(
142: lShortcut)
143: .addPreferredGap(
144: org.jdesktop.layout.LayoutStyle.RELATED)
145: .add(
146: tfShortcut,
147: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
148: 406,
149: Short.MAX_VALUE)))
150: .addContainerGap()));
151: layout
152: .setVerticalGroup(layout
153: .createParallelGroup(
154: org.jdesktop.layout.GroupLayout.LEADING)
155: .add(
156: layout
157: .createSequentialGroup()
158: .addContainerGap()
159: .add(
160: layout
161: .createParallelGroup(
162: org.jdesktop.layout.GroupLayout.BASELINE)
163: .add(lShortcut)
164: .add(
165: tfShortcut,
166: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
167: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
168: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
169: .addPreferredGap(
170: org.jdesktop.layout.LayoutStyle.RELATED)
171: .add(lConflict)
172: .addContainerGap(41,
173: Short.MAX_VALUE)));
174:
175: getAccessibleContext().setAccessibleName(
176: org.openide.util.NbBundle.getMessage(
177: ShortcutsDialog.class, "AN_ShortcutsDialog")); // NOI18N
178: getAccessibleContext().setAccessibleDescription(
179: org.openide.util.NbBundle.getMessage(
180: ShortcutsDialog.class, "AD_ShortcutsDialog")); // NOI18N
181: }// </editor-fold>//GEN-END:initComponents
182:
183: // Variables declaration - do not modify//GEN-BEGIN:variables
184: private javax.swing.JLabel lConflict;
185: private javax.swing.JLabel lShortcut;
186: private javax.swing.JTextField tfShortcut;
187:
188: // End of variables declaration//GEN-END:variables
189:
190: class Listener implements ActionListener, KeyListener {
191:
192: private KeyStroke backspaceKS = KeyStroke.getKeyStroke(
193: KeyEvent.VK_BACK_SPACE, 0);
194: private KeyStroke tabKS = KeyStroke.getKeyStroke(
195: KeyEvent.VK_TAB, 0);
196:
197: private String key = ""; //NOI18N
198:
199: public void keyTyped(KeyEvent e) {
200: e.consume();
201: }
202:
203: public void keyPressed(KeyEvent e) {
204: KeyStroke keyStroke = KeyStroke.getKeyStroke(
205: e.getKeyCode(), e.getModifiers());
206:
207: boolean add = e.getKeyCode() != KeyEvent.VK_SHIFT
208: && e.getKeyCode() != KeyEvent.VK_CONTROL
209: && e.getKeyCode() != KeyEvent.VK_ALT
210: && e.getKeyCode() != KeyEvent.VK_META
211: && e.getKeyCode() != KeyEvent.VK_ALT_GRAPH;
212:
213: if (keyStroke.equals(backspaceKS) && !key.equals("")) {
214: // delete last key
215: int i = key.lastIndexOf(' '); //NOI18N
216: if (i < 0) {
217: key = ""; //NOI18N
218: } else {
219: key = key.substring(0, i);
220: }
221: getTfShortcut().setText(key);
222: } else {
223: // add key
224: addKeyStroke(keyStroke, add);
225: }
226: if (add) {
227: updateWarning();
228: } else {
229: setShortcutValid(false);
230: }
231: e.consume();
232: }
233:
234: public void keyReleased(KeyEvent e) {
235: e.consume();
236: }
237:
238: public void actionPerformed(ActionEvent e) {
239: if (e.getSource() == getBClear()) {
240: key = ""; //NOI18N
241: getTfShortcut().setText(key);
242: } else if (e.getSource() == getBTab()) {
243: addKeyStroke(tabKS, true);
244: }
245: updateWarning();
246: }
247:
248: private void updateWarning() {
249: String text = getTfShortcut().getText();
250: ShortcutAction action = f.findActionForShortcut(text);
251: if (action != null) {
252: lConflict.setText(MessageFormat.format(
253: loc("Shortcut_Conflict"), //NOI18N
254: new Object[] { action.getDisplayName() }));
255: setShortcutValid(true);
256: } else {
257: lConflict.setText(""); //NOI18N
258: setShortcutValid(text != null && text.length() > 0);
259: }
260: }
261:
262: private void addKeyStroke(KeyStroke keyStroke, boolean add) {
263: String k = Utils.getKeyStrokeAsText(keyStroke);
264: if (key.equals("")) { //NOI18N
265: getTfShortcut().setText(k);
266: if (add)
267: key = k;
268: } else {
269: getTfShortcut().setText(key + " " + k); //NOI18N
270: if (add)
271: key += " " + k; //NOI18N
272: }
273: }
274: }
275:
276: public JButton getBTab() {
277: return bTab;
278: }
279:
280: public JButton getBClear() {
281: return bClear;
282: }
283:
284: public boolean isShortcutValid() {
285: return shortcutValid;
286: }
287:
288: private void setShortcutValid(boolean valid) {
289: if (valid != shortcutValid) {
290: shortcutValid = valid;
291: firePropertyChange(PROP_SHORTCUT_VALID, !shortcutValid,
292: shortcutValid);
293: }
294: }
295: }
|