KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > gui > GrabKeyDialog


1 /*
2  * GrabKeyDialog.java - Grabs keys from the keyboard
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2001, 2002 Slava Pestov
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */

22
23 package org.gjt.sp.jedit.gui;
24
25 //{{{ Imports
26
import javax.swing.border.*;
27 import javax.swing.*;
28 import java.awt.event.*;
29 import java.awt.*;
30 import java.lang.reflect.Field JavaDoc;
31 import java.util.*;
32 import org.gjt.sp.jedit.*;
33 import org.gjt.sp.util.Log;
34 //}}}
35

36 /**
37  * A dialog for getting shortcut keys.
38  */

39 public class GrabKeyDialog extends JDialog
40 {
41     //{{{ toString() method
42
public static String JavaDoc toString(KeyEvent evt)
43     {
44         String JavaDoc id;
45         switch(evt.getID())
46         {
47         case KeyEvent.KEY_PRESSED:
48             id = "KEY_PRESSED";
49             break;
50         case KeyEvent.KEY_RELEASED:
51             id = "KEY_RELEASED";
52             break;
53         case KeyEvent.KEY_TYPED:
54             id = "KEY_TYPED";
55             break;
56         default:
57             id = "unknown type";
58             break;
59         }
60         
61         StringBuilder JavaDoc b = new StringBuilder JavaDoc(50);
62
63         b.append(id + ",keyCode=0x"
64             + Integer.toString(evt.getKeyCode(),16)
65             + ",keyChar=0x"
66             + Integer.toString(evt.getKeyChar(),16)
67             + ",modifiers=0x"
68             + Integer.toString(evt.getModifiers(),16));
69         
70         b.append(",consumed=");
71         b.append(evt.isConsumed()?'1':'0');
72             
73         return b.toString();
74     } //}}}
75

76     //{{{ GrabKeyDialog constructor
77
/**
78      * Create and show a new modal dialog.
79      *
80      * @param parent center dialog on this component.
81      * @param binding the action/macro that should get a binding.
82      * @param allBindings all other key bindings.
83      * @param debugBuffer debug info will be dumped to this buffer
84      * (may be null)
85      * @since jEdit 4.1pre7
86      */

87     public GrabKeyDialog(Dialog parent, KeyBinding binding,
88         Vector allBindings, Buffer debugBuffer)
89     {
90         super(parent,jEdit.getProperty("grab-key.title"),true);
91
92         init(binding,allBindings,debugBuffer);
93     } //}}}
94

95     //{{{ GrabKeyDialog constructor
96
/**
97      * Create and show a new modal dialog.
98      *
99      * @param parent center dialog on this component.
100      * @param binding the action/macro that should get a binding.
101      * @param allBindings all other key bindings.
102      * @param debugBuffer debug info will be dumped to this buffer
103      * (may be null)
104      * @since jEdit 4.1pre7
105      */

106     public GrabKeyDialog(Frame parent, KeyBinding binding,
107         Vector allBindings, Buffer debugBuffer)
108     {
109         super(parent,jEdit.getProperty("grab-key.title"),true);
110
111         init(binding,allBindings,debugBuffer);
112     } //}}}
113

114     //{{{ getShortcut() method
115
/**
116      * Returns the shortcut, or null if the current shortcut should be
117      * removed or the dialog either has been cancelled. Use isOK()
118      * to determine if the latter is true.
119      */

120     public String JavaDoc getShortcut()
121     {
122         if(isOK)
123             return shortcut.getText();
124         else
125             return null;
126     } //}}}
127

128     //{{{ isOK() method
129
/**
130      * Returns true, if the dialog has not been cancelled.
131      * @since jEdit 3.2pre9
132      */

133     public boolean isOK()
134     {
135         return isOK;
136     } //}}}
137

138     //{{{ isManagingFocus() method
139
/**
140      * Returns if this component can be traversed by pressing the
141      * Tab key. This returns false.
142      */

143     public boolean isManagingFocus()
144     {
145         return false;
146     } //}}}
147

148     //{{{ getFocusTraversalKeysEnabled() method
149
/**
150      * Makes the tab key work in Java 1.4.
151      * @since jEdit 3.2pre4
152      */

153     public boolean getFocusTraversalKeysEnabled()
154     {
155         return false;
156     } //}}}
157

158     //{{{ processKeyEvent() method
159
protected void processKeyEvent(KeyEvent evt)
160     {
161         shortcut.processKeyEvent(evt);
162     } //}}}
163

164     //{{{ Private members
165

166     //{{{ Instance variables
167
private InputPane shortcut; // this is a bad hack
168
private JLabel assignedTo;
169     private JButton ok;
170     private JButton remove;
171     private JButton cancel;
172     private JButton clear;
173     private boolean isOK;
174     private KeyBinding binding;
175     private Vector allBindings;
176     private Buffer debugBuffer;
177     //}}}
178

179     //{{{ init() method
180
private void init(KeyBinding binding, Vector allBindings, Buffer debugBuffer)
181     {
182         this.binding = binding;
183         this.allBindings = allBindings;
184         this.debugBuffer = debugBuffer;
185
186         enableEvents(AWTEvent.KEY_EVENT_MASK);
187
188         // create a panel with a BoxLayout. Can't use Box here
189
// because Box doesn't have setBorder().
190
JPanel content = new JPanel(new GridLayout(0,1,0,6))
191         {
192             /**
193              * Returns if this component can be traversed by pressing the
194              * Tab key. This returns false.
195              */

196             public boolean isManagingFocus()
197             {
198                 return false;
199             }
200
201             /**
202              * Makes the tab key work in Java 1.4.
203              * @since jEdit 3.2pre4
204              */

205             public boolean getFocusTraversalKeysEnabled()
206             {
207                 return false;
208             }
209         };
210         content.setBorder(new EmptyBorder(12,12,12,12));
211         setContentPane(content);
212
213         JLabel label = new JLabel(
214             debugBuffer == null ? jEdit.getProperty(
215             "grab-key.caption",new String JavaDoc[] { binding.label })
216             : jEdit.getProperty("grab-key.keyboard-test"));
217
218         Box input = Box.createHorizontalBox();
219
220         shortcut = new InputPane();
221         Dimension size = shortcut.getPreferredSize();
222         size.width = Integer.MAX_VALUE;
223         shortcut.setMaximumSize(size);
224         input.add(shortcut);
225         input.add(Box.createHorizontalStrut(12));
226
227         clear = new JButton(jEdit.getProperty("grab-key.clear"));
228         clear.addActionListener(new ActionHandler());
229         input.add(clear);
230
231         assignedTo = new JLabel();
232         if(debugBuffer == null)
233             updateAssignedTo(null);
234
235         Box buttons = Box.createHorizontalBox();
236         buttons.add(Box.createGlue());
237
238         if(debugBuffer == null)
239         {
240             ok = new JButton(jEdit.getProperty("common.ok"));
241             ok.addActionListener(new ActionHandler());
242             buttons.add(ok);
243             buttons.add(Box.createHorizontalStrut(12));
244
245             if(binding.isAssigned()) {
246                 // show "remove" button
247
remove = new JButton(jEdit.getProperty("grab-key.remove"));
248                 remove.addActionListener(new ActionHandler());
249                 buttons.add(remove);
250                 buttons.add(Box.createHorizontalStrut(12));
251             }
252         }
253
254         cancel = new JButton(jEdit.getProperty("common.cancel"));
255         cancel.addActionListener(new ActionHandler());
256         buttons.add(cancel);
257         buttons.add(Box.createGlue());
258
259         content.add(label);
260         content.add(input);
261         if(debugBuffer == null)
262             content.add(assignedTo);
263         content.add(buttons);
264
265         setDefaultCloseOperation(DISPOSE_ON_CLOSE);
266
267         pack();
268         setLocationRelativeTo(getParent());
269         setResizable(false);
270         setVisible(true);
271     } //}}}
272

273     //{{{ getSymbolicName() method
274
public static String JavaDoc getSymbolicName(int keyCode)
275     {
276         if (Debug.DUMP_KEY_EVENTS) {
277             Log.log(Log.DEBUG,GrabKeyDialog.class,"getSymbolicName("+keyCode+").");
278         }
279         
280         if(keyCode == KeyEvent.VK_UNDEFINED)
281             return null;
282         /* else if(keyCode == KeyEvent.VK_OPEN_BRACKET)
283             return "[";
284         else if(keyCode == KeyEvent.VK_CLOSE_BRACKET)
285             return "]"; */

286
287         if(keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z)
288             return String.valueOf(Character.toLowerCase((char)keyCode));
289
290         try
291         {
292             Field JavaDoc[] fields = KeyEvent.class.getFields();
293             for(int i = 0; i < fields.length; i++)
294             {
295                 Field JavaDoc field = fields[i];
296                 String JavaDoc name = field.getName();
297                 if(name.startsWith("VK_")
298                     && field.getInt(null) == keyCode)
299                 {
300                     return name.substring(3);
301                 }
302             }
303         }
304         catch(Exception JavaDoc e)
305         {
306             Log.log(Log.ERROR,GrabKeyDialog.class,e);
307         }
308
309         return null;
310     } //}}}
311

312     //{{{ updateAssignedTo() method
313
private void updateAssignedTo(String JavaDoc shortcut)
314     {
315         String JavaDoc text = jEdit.getProperty("grab-key.assigned-to.none");
316         KeyBinding kb = getKeyBinding(shortcut);
317
318         if(kb != null)
319             if(kb.isPrefix)
320                 text = jEdit.getProperty(
321                     "grab-key.assigned-to.prefix",
322                     new String JavaDoc[] { shortcut });
323             else
324                 text = kb.label;
325
326         if(ok != null)
327             ok.setEnabled(kb == null || !kb.isPrefix);
328
329         assignedTo.setText(
330             jEdit.getProperty("grab-key.assigned-to",
331                 new String JavaDoc[] { text }));
332     } //}}}
333

334     //{{{ getKeyBinding() method
335
private KeyBinding getKeyBinding(String JavaDoc shortcut)
336     {
337         if(shortcut == null || shortcut.length() == 0)
338             return null;
339
340         String JavaDoc spacedShortcut = shortcut + " ";
341         Enumeration e = allBindings.elements();
342
343         while(e.hasMoreElements())
344         {
345             KeyBinding kb = (KeyBinding)e.nextElement();
346
347             if(!kb.isAssigned())
348                 continue;
349
350             String JavaDoc spacedKbShortcut = kb.shortcut + " ";
351
352             // eg, trying to bind C+n C+p if C+n already bound
353
if(spacedShortcut.startsWith(spacedKbShortcut))
354                 return kb;
355
356             // eg, trying to bind C+e if C+e is a prefix
357
if(spacedKbShortcut.startsWith(spacedShortcut))
358             {
359                 // create a temporary (synthetic) prefix
360
// KeyBinding, that won't be saved
361
return new KeyBinding(kb.name,kb.label,
362                     shortcut,true);
363             }
364         }
365
366         return null;
367     } //}}}
368

369     //}}}
370

371     //{{{ KeyBinding class
372
/**
373      * A jEdit action or macro with its two possible shortcuts.
374      * @since jEdit 3.2pre8
375      */

376     public static class KeyBinding
377     {
378         public KeyBinding(String JavaDoc name, String JavaDoc label,
379             String JavaDoc shortcut, boolean isPrefix)
380         {
381             this.name = name;
382             this.label = label;
383             this.shortcut = shortcut;
384             this.isPrefix = isPrefix;
385         }
386
387         public String JavaDoc name;
388         public String JavaDoc label;
389         public String JavaDoc shortcut;
390         public boolean isPrefix;
391
392         public boolean isAssigned()
393         {
394             return shortcut != null && shortcut.length() > 0;
395         }
396     } //}}}
397

398     //{{{ InputPane class
399
class InputPane extends JTextField
400     {
401         //{{{ getFocusTraversalKeysEnabled() method
402
/**
403          * Makes the tab key work in Java 1.4.
404          * @since jEdit 3.2pre4
405          */

406         public boolean getFocusTraversalKeysEnabled()
407         {
408             return false;
409         } //}}}
410

411         //{{{ processKeyEvent() method
412
protected void processKeyEvent(KeyEvent _evt)
413         {
414             KeyEvent evt = KeyEventWorkaround.processKeyEvent(_evt);
415             if(!KeyEventWorkaround.isBindable(_evt.getKeyCode()))
416                 evt = null;
417
418             if(debugBuffer != null)
419             {
420                 debugBuffer.insert(debugBuffer.getLength(),
421                     "Event " + GrabKeyDialog.toString(_evt)
422                     + (evt == null ? " filtered\n"
423                     : " passed\n"));
424             }
425
426             if(evt == null)
427                 return;
428
429             evt.consume();
430
431             KeyEventTranslator.Key key = KeyEventTranslator
432                 .translateKeyEvent(evt);
433                 
434             if (Debug.DUMP_KEY_EVENTS) {
435                 Log.log(Log.DEBUG,GrabKeyDialog.class,"processKeyEvent() key="+key+", _evt="+_evt+".");
436             }
437
438             if(key == null)
439                 return;
440
441             if(debugBuffer != null)
442             {
443                 debugBuffer.insert(debugBuffer.getLength(),
444                     "==> Translated to " + key + "\n");
445             }
446
447             StringBuffer JavaDoc keyString = new StringBuffer JavaDoc(getText());
448
449             if(getDocument().getLength() != 0)
450                 keyString.append(' ');
451
452             if (!Options.SIMPLIFIED_KEY_HANDLING) {
453                 if(key.modifiers != null)
454                     keyString.append(key.modifiers).append('+');
455     
456                 if(key.input == ' ')
457                     keyString.append("SPACE");
458                 else if(key.input != '\0')
459                     keyString.append(key.input);
460                 else
461                 {
462                     String JavaDoc symbolicName = getSymbolicName(key.key);
463     
464                     if(symbolicName == null)
465                         return;
466     
467                     keyString.append(symbolicName);
468                 }
469             } else {
470                 if(key.modifiers != null) {
471                     keyString.append(key.modifiers).append('+');
472                 }
473                 
474                 String JavaDoc symbolicName = getSymbolicName(key.key);
475
476                 if(symbolicName != null) {
477                     keyString.append(symbolicName);
478                 } else {
479                     if (key.input != '\0') {
480                         if (key.input == ' ') {
481                             keyString.append("SPACE");
482                         } else {
483                             keyString.append(key.input);
484                         }
485                     } else {
486                         return;
487                     }
488                 }
489
490             }
491
492             setText(keyString.toString());
493             if(debugBuffer == null)
494                 updateAssignedTo(keyString.toString());
495         } //}}}
496
} //}}}
497

498     //{{{ ActionHandler class
499
class ActionHandler implements ActionListener
500     {
501         //{{{ actionPerformed() method
502
public void actionPerformed(ActionEvent evt)
503         {
504             if(evt.getSource() == ok)
505             {
506                 if(canClose())
507                     dispose();
508             }
509             else if(evt.getSource() == remove)
510             {
511                 shortcut.setText(null);
512                 isOK = true;
513                 dispose();
514             }
515             else if(evt.getSource() == cancel)
516                 dispose();
517             else if(evt.getSource() == clear)
518             {
519                 shortcut.setText(null);
520                 if(debugBuffer == null)
521                     updateAssignedTo(null);
522                 shortcut.requestFocus();
523             }
524         } //}}}
525

526         //{{{ canClose() method
527
private boolean canClose()
528         {
529             String JavaDoc shortcutString = shortcut.getText();
530             if(shortcutString.length() == 0
531                 && binding.isAssigned())
532             {
533                 // ask whether to remove the old shortcut
534
int answer = GUIUtilities.confirm(
535                     GrabKeyDialog.this,
536                     "grab-key.remove-ask",
537                     null,
538                     JOptionPane.YES_NO_OPTION,
539                     JOptionPane.QUESTION_MESSAGE);
540                 if(answer == JOptionPane.YES_OPTION)
541                 {
542                     shortcut.setText(null);
543                     isOK = true;
544                 }
545                 else
546                     return false;
547             }
548
549             // check whether this shortcut already exists
550
KeyBinding other = getKeyBinding(shortcutString);
551             if(other == null || other == binding)
552             {
553                 isOK = true;
554                 return true;
555             }
556
557             // check whether the other shortcut is the alt. shortcut
558
if(other.name == binding.name)
559             {
560                 // we don't need two identical shortcuts
561
GUIUtilities.error(GrabKeyDialog.this,
562                     "grab-key.duplicate-alt-shortcut",
563                     null);
564                 return false;
565             }
566
567             // check whether shortcut is a prefix to others
568
if(other.isPrefix)
569             {
570                 // can't override prefix shortcuts
571
GUIUtilities.error(GrabKeyDialog.this,
572                     "grab-key.prefix-shortcut",
573                     null);
574                 return false;
575             }
576
577             // ask whether to override that other shortcut
578
int answer = GUIUtilities.confirm(GrabKeyDialog.this,
579                 "grab-key.duplicate-shortcut",
580                 new Object JavaDoc[] { other.label },
581                 JOptionPane.YES_NO_OPTION,
582                 JOptionPane.QUESTION_MESSAGE);
583             if(answer == JOptionPane.YES_OPTION)
584             {
585                 if(other.shortcut != null
586                     && shortcutString.startsWith(other.shortcut))
587                 {
588                     other.shortcut = null;
589                 }
590                 isOK = true;
591                 return true;
592             }
593             else
594                 return false;
595         } //}}}
596
} //}}}
597
}
598
Popular Tags