KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > syntax > jedit > DefaultInputHandler


1 /*
2  * Copyright (C) 2005 - 2006 JasperSoft Corporation. All rights reserved.
3  * http://www.jaspersoft.com.
4  *
5  * Unless you have purchased a commercial license agreement from JasperSoft,
6  * the following license terms apply:
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as published by
10  * the Free Software Foundation.
11  *
12  * This program is distributed WITHOUT ANY WARRANTY; and without the
13  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
18  * or write to:
19  *
20  * Free Software Foundation, Inc.,
21  * 59 Temple Place - Suite 330,
22  * Boston, MA USA 02111-1307
23  *
24  *
25  *
26  *
27  * DefaultInputHandler.java
28  *
29  */

30
31 package org.syntax.jedit;
32
33 import javax.swing.KeyStroke JavaDoc;
34 import java.awt.event.*;
35 import java.awt.Toolkit JavaDoc;
36 import java.util.Hashtable JavaDoc;
37 import java.util.StringTokenizer JavaDoc;
38
39 /**
40  * The default input handler. It maps sequences of keystrokes into actions
41  * and inserts key typed events into the text area.
42  * @author Slava Pestov
43  * @version $Id: DefaultInputHandler.java 932 2006-10-20 09:32:45Z gtoffoli $
44  */

45 public class DefaultInputHandler extends InputHandler
46 {
47     /**
48      * Creates a new input handler with no key bindings defined.
49      */

50     public DefaultInputHandler()
51     {
52         bindings = currentBindings = new Hashtable JavaDoc();
53     }
54
55     /**
56      * Sets up the default key bindings.
57      */

58     public void addDefaultKeyBindings()
59     {
60         addKeyBinding("BACK_SPACE",BACKSPACE);
61         addKeyBinding("C+BACK_SPACE",BACKSPACE_WORD);
62         addKeyBinding("DELETE",DELETE);
63         addKeyBinding("C+DELETE",DELETE_WORD);
64
65         addKeyBinding("ENTER",INSERT_BREAK);
66         addKeyBinding("TAB",INSERT_TAB);
67
68         addKeyBinding("INSERT",OVERWRITE);
69         addKeyBinding("C+\\",TOGGLE_RECT);
70
71         addKeyBinding("HOME",HOME);
72         addKeyBinding("END",END);
73         addKeyBinding("C+A",SELECT_ALL);
74         addKeyBinding("S+HOME",SELECT_HOME);
75         addKeyBinding("S+END",SELECT_END);
76         addKeyBinding("C+HOME",DOCUMENT_HOME);
77         addKeyBinding("C+END",DOCUMENT_END);
78         addKeyBinding("CS+HOME",SELECT_DOC_HOME);
79         addKeyBinding("CS+END",SELECT_DOC_END);
80
81         addKeyBinding("PAGE_UP",PREV_PAGE);
82         addKeyBinding("PAGE_DOWN",NEXT_PAGE);
83         addKeyBinding("S+PAGE_UP",SELECT_PREV_PAGE);
84         addKeyBinding("S+PAGE_DOWN",SELECT_NEXT_PAGE);
85
86         addKeyBinding("LEFT",PREV_CHAR);
87         addKeyBinding("S+LEFT",SELECT_PREV_CHAR);
88         addKeyBinding("C+LEFT",PREV_WORD);
89         addKeyBinding("CS+LEFT",SELECT_PREV_WORD);
90         addKeyBinding("RIGHT",NEXT_CHAR);
91         addKeyBinding("S+RIGHT",SELECT_NEXT_CHAR);
92         addKeyBinding("C+RIGHT",NEXT_WORD);
93         addKeyBinding("CS+RIGHT",SELECT_NEXT_WORD);
94         addKeyBinding("UP",PREV_LINE);
95         addKeyBinding("S+UP",SELECT_PREV_LINE);
96         addKeyBinding("DOWN",NEXT_LINE);
97         addKeyBinding("S+DOWN",SELECT_NEXT_LINE);
98
99         addKeyBinding("C+ENTER",REPEAT);
100         
101         // Clipboard
102
addKeyBinding("C+C", CLIP_COPY);
103         addKeyBinding("C+V", CLIP_PASTE);
104         addKeyBinding("C+X", CLIP_CUT);
105                 
106                 addKeyBinding("C+Z", UNDO);
107                 addKeyBinding("C+Y", REDO);
108     }
109
110     /**
111      * Adds a key binding to this input handler. The key binding is
112      * a list of white space separated key strokes of the form
113      * <i>[modifiers+]key</i> where modifier is C for Control, A for Alt,
114      * or S for Shift, and key is either a character (a-z) or a field
115      * name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE)
116      * @param keyBinding The key binding
117      * @param action The action
118      */

119     public void addKeyBinding(String JavaDoc keyBinding, ActionListener action)
120     {
121             Hashtable JavaDoc current = bindings;
122
123         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(keyBinding);
124         while(st.hasMoreTokens())
125         {
126             KeyStroke JavaDoc keyStroke = parseKeyStroke(st.nextToken());
127             if(keyStroke == null)
128                 return;
129
130             if(st.hasMoreTokens())
131             {
132                 Object JavaDoc o = current.get(keyStroke);
133                 if(o instanceof Hashtable JavaDoc)
134                     current = (Hashtable JavaDoc)o;
135                 else
136                 {
137                     o = new Hashtable JavaDoc();
138                     current.put(keyStroke,o);
139                     current = (Hashtable JavaDoc)o;
140                 }
141             }
142             else
143                 current.put(keyStroke,action);
144         }
145     }
146
147     /**
148      * Removes a key binding from this input handler. This is not yet
149      * implemented.
150      * @param keyBinding The key binding
151      */

152     public void removeKeyBinding(String JavaDoc keyBinding)
153     {
154         throw new InternalError JavaDoc("Not yet implemented");
155     }
156
157     /**
158      * Removes all key bindings from this input handler.
159      */

160     public void removeAllKeyBindings()
161     {
162         bindings.clear();
163     }
164
165     /**
166      * Returns a copy of this input handler that shares the same
167      * key bindings. Setting key bindings in the copy will also
168      * set them in the original.
169      */

170     public InputHandler copy()
171     {
172         return new DefaultInputHandler(this);
173     }
174
175     /**
176      * Handle a key pressed event. This will look up the binding for
177      * the key stroke and execute it.
178      */

179     public void keyPressed(KeyEvent evt)
180     {
181         int keyCode = evt.getKeyCode();
182         int modifiers = evt.getModifiers();
183
184         if(keyCode == KeyEvent.VK_CONTROL ||
185             keyCode == KeyEvent.VK_SHIFT ||
186             keyCode == KeyEvent.VK_ALT ||
187             keyCode == KeyEvent.VK_META)
188             return;
189
190         if((modifiers & ~KeyEvent.SHIFT_MASK) != 0
191             || evt.isActionKey()
192             || keyCode == KeyEvent.VK_BACK_SPACE
193             || keyCode == KeyEvent.VK_DELETE
194             || keyCode == KeyEvent.VK_ENTER
195             || keyCode == KeyEvent.VK_TAB
196             || keyCode == KeyEvent.VK_ESCAPE)
197         {
198             if(grabAction != null)
199             {
200                 handleGrabAction(evt);
201                 return;
202             }
203
204             KeyStroke JavaDoc keyStroke = KeyStroke.getKeyStroke(keyCode,
205                 modifiers);
206             Object JavaDoc o = currentBindings.get(keyStroke);
207             if(o == null)
208             {
209                 // Don't beep if the user presses some
210
// key we don't know about unless a
211
// prefix is active. Otherwise it will
212
// beep when caps lock is pressed, etc.
213
if(currentBindings != bindings)
214                 {
215                     Toolkit.getDefaultToolkit().beep();
216                     // F10 should be passed on, but C+e F10
217
// shouldn't
218
repeatCount = 0;
219                     repeat = false;
220                     evt.consume();
221                 }
222                 currentBindings = bindings;
223                 return;
224             }
225             else if(o instanceof ActionListener)
226             {
227                 currentBindings = bindings;
228                 executeAction(((ActionListener)o),
229                     evt.getSource(),null);
230
231                 evt.consume();
232                 return;
233             }
234             else if(o instanceof Hashtable JavaDoc)
235             {
236                 currentBindings = (Hashtable JavaDoc)o;
237                 evt.consume();
238                 return;
239             }
240         }
241     }
242
243     /**
244      * Handle a key typed event. This inserts the key into the text area.
245      */

246     public void keyTyped(KeyEvent evt)
247     {
248         int modifiers = evt.getModifiers();
249         char c = evt.getKeyChar();
250         if(c != KeyEvent.CHAR_UNDEFINED &&
251             (modifiers & KeyEvent.ALT_MASK) == 0)
252         {
253             if(c >= 0x20 && c != 0x7f)
254             {
255                 KeyStroke JavaDoc keyStroke = KeyStroke.getKeyStroke(
256                     Character.toUpperCase(c));
257                 Object JavaDoc o = currentBindings.get(keyStroke);
258
259                 if(o instanceof Hashtable JavaDoc)
260                 {
261                     currentBindings = (Hashtable JavaDoc)o;
262                     return;
263                 }
264                 else if(o instanceof ActionListener)
265                 {
266                     currentBindings = bindings;
267                     executeAction((ActionListener)o,
268                         evt.getSource(),
269                         String.valueOf(c));
270                     return;
271                 }
272
273                 currentBindings = bindings;
274
275                 if(grabAction != null)
276                 {
277                     handleGrabAction(evt);
278                     return;
279                 }
280
281                 // 0-9 adds another 'digit' to the repeat number
282
if(repeat && Character.isDigit(c))
283                 {
284                     repeatCount *= 10;
285                     repeatCount += (c - '0');
286                     return;
287                 }
288
289                 executeAction(INSERT_CHAR,evt.getSource(),
290                     String.valueOf(evt.getKeyChar()));
291
292                 repeatCount = 0;
293                 repeat = false;
294             }
295         }
296     }
297
298     /**
299      * Converts a string to a keystroke. The string should be of the
300      * form <i>modifiers</i>+<i>shortcut</i> where <i>modifiers</i>
301      * is any combination of A for Alt, C for Control, S for Shift
302      * or M for Meta, and <i>shortcut</i> is either a single character,
303      * or a keycode name from the <code>KeyEvent</code> class, without
304      * the <code>VK_</code> prefix.
305      * @param keyStroke A string description of the key stroke
306      */

307     public static KeyStroke JavaDoc parseKeyStroke(String JavaDoc keyStroke)
308     {
309         if(keyStroke == null)
310             return null;
311         int modifiers = 0;
312         int index = keyStroke.indexOf('+');
313         if(index != -1)
314         {
315             for(int i = 0; i < index; i++)
316             {
317                 switch(Character.toUpperCase(keyStroke
318                     .charAt(i)))
319                 {
320                 case 'A':
321                     modifiers |= InputEvent.ALT_MASK;
322                     break;
323                 case 'C':
324                     modifiers |= InputEvent.CTRL_MASK;
325                     break;
326                 case 'M':
327                     modifiers |= InputEvent.META_MASK;
328                     break;
329                 case 'S':
330                     modifiers |= InputEvent.SHIFT_MASK;
331                     break;
332                 }
333             }
334         }
335         String JavaDoc key = keyStroke.substring(index + 1);
336         if(key.length() == 1)
337         {
338             char ch = Character.toUpperCase(key.charAt(0));
339             if(modifiers == 0)
340                 return KeyStroke.getKeyStroke(ch);
341             else
342                 return KeyStroke.getKeyStroke(ch,modifiers);
343         }
344         else if(key.length() == 0)
345         {
346             System.err.println("Invalid key stroke: " + keyStroke);
347             return null;
348         }
349         else
350         {
351             int ch;
352
353             try
354             {
355                 ch = KeyEvent.class.getField("VK_".concat(key))
356                     .getInt(null);
357             }
358             catch(Exception JavaDoc e)
359             {
360                 System.err.println("Invalid key stroke: "
361                     + keyStroke);
362                 return null;
363             }
364
365             return KeyStroke.getKeyStroke(ch,modifiers);
366         }
367     }
368
369     // private members
370
private Hashtable JavaDoc bindings;
371     private Hashtable JavaDoc currentBindings;
372
373     private DefaultInputHandler(DefaultInputHandler copy)
374     {
375         bindings = currentBindings = copy.bindings;
376     }
377         
378         
379 }
380
Popular Tags