KickJava   Java API By Example, From Geeks To Geeks.

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


1 package org.jedit.syntax;
2
3 /*
4  * DefaultInputHandler.java - Default implementation of an input handler
5  * Copyright (C) 1999 Slava Pestov
6  *
7  * You may use and modify this package for any purpose. Redistribution is
8  * permitted, in both source and binary form, provided that this notice
9  * remains intact in all source distributions of this package.
10  */

11
12 import javax.swing.KeyStroke JavaDoc;
13 import java.awt.event.*;
14 import java.awt.Toolkit JavaDoc;
15 import java.util.Hashtable JavaDoc;
16 import java.util.StringTokenizer JavaDoc;
17
18 /**
19  * The default input handler. It maps sequences of keystrokes into actions
20  * and inserts key typed events into the text area.
21  * @author Slava Pestov
22  * @version $Id: DefaultInputHandler.java,v 1.1 2003/12/14 16:29:49 daggerrz Exp $
23  */

24 public class DefaultInputHandler extends InputHandler
25 {
26    /**
27     * Creates a new input handler with no key bindings defined.
28     */

29    public DefaultInputHandler()
30    {
31       bindings = currentBindings = new Hashtable JavaDoc();
32    }
33
34    /**
35     * Sets up the default key bindings.
36     */

37    public void addDefaultKeyBindings()
38    {
39       addKeyBinding("BACK_SPACE",BACKSPACE);
40       addKeyBinding("C+BACK_SPACE",BACKSPACE_WORD);
41       addKeyBinding("DELETE",DELETE);
42       addKeyBinding("C+DELETE",DELETE_WORD);
43
44       addKeyBinding("ENTER",INSERT_BREAK);
45       addKeyBinding("TAB",INSERT_TAB);
46
47       addKeyBinding("INSERT",OVERWRITE);
48       addKeyBinding("C+\\",TOGGLE_RECT);
49
50       addKeyBinding("HOME",HOME);
51       addKeyBinding("END",END);
52       addKeyBinding("S+HOME",SELECT_HOME);
53       addKeyBinding("S+END",SELECT_END);
54       addKeyBinding("C+HOME",DOCUMENT_HOME);
55       addKeyBinding("C+END",DOCUMENT_END);
56       addKeyBinding("CS+HOME",SELECT_DOC_HOME);
57       addKeyBinding("CS+END",SELECT_DOC_END);
58
59       addKeyBinding("PAGE_UP",PREV_PAGE);
60       addKeyBinding("PAGE_DOWN",NEXT_PAGE);
61       addKeyBinding("S+PAGE_UP",SELECT_PREV_PAGE);
62       addKeyBinding("S+PAGE_DOWN",SELECT_NEXT_PAGE);
63
64       addKeyBinding("LEFT",PREV_CHAR);
65       addKeyBinding("S+LEFT",SELECT_PREV_CHAR);
66       addKeyBinding("C+LEFT",PREV_WORD);
67       addKeyBinding("CS+LEFT",SELECT_PREV_WORD);
68       addKeyBinding("RIGHT",NEXT_CHAR);
69       addKeyBinding("S+RIGHT",SELECT_NEXT_CHAR);
70       addKeyBinding("C+RIGHT",NEXT_WORD);
71       addKeyBinding("CS+RIGHT",SELECT_NEXT_WORD);
72       addKeyBinding("UP",PREV_LINE);
73       addKeyBinding("S+UP",SELECT_PREV_LINE);
74       addKeyBinding("DOWN",NEXT_LINE);
75       addKeyBinding("S+DOWN",SELECT_NEXT_LINE);
76
77       addKeyBinding("C+ENTER",REPEAT);
78    }
79
80    /**
81     * Adds a key binding to this input handler. The key binding is
82     * a list of white space separated key strokes of the form
83     * <i>[modifiers+]key</i> where modifier is C for Control, A for Alt,
84     * or S for Shift, and key is either a character (a-z) or a field
85     * name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE)
86     * @param keyBinding The key binding
87     * @param action The action
88     */

89    public void addKeyBinding(String JavaDoc keyBinding, ActionListener action)
90    {
91            Hashtable JavaDoc current = bindings;
92
93       StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(keyBinding);
94       while(st.hasMoreTokens())
95       {
96          KeyStroke JavaDoc keyStroke = parseKeyStroke(st.nextToken());
97          if(keyStroke == null)
98             return;
99
100          if(st.hasMoreTokens())
101          {
102             Object JavaDoc o = current.get(keyStroke);
103             if(o instanceof Hashtable JavaDoc)
104                current = (Hashtable JavaDoc)o;
105             else
106             {
107                o = new Hashtable JavaDoc();
108                current.put(keyStroke,o);
109                current = (Hashtable JavaDoc)o;
110             }
111          }
112          else
113             current.put(keyStroke,action);
114       }
115    }
116
117    /**
118     * Removes a key binding from this input handler. This is not yet
119     * implemented.
120     * @param keyBinding The key binding
121     */

122    public void removeKeyBinding(String JavaDoc keyBinding)
123    {
124       throw new InternalError JavaDoc("Not yet implemented");
125    }
126
127    /**
128     * Removes all key bindings from this input handler.
129     */

130    public void removeAllKeyBindings()
131    {
132       bindings.clear();
133    }
134
135    /**
136     * Returns a copy of this input handler that shares the same
137     * key bindings. Setting key bindings in the copy will also
138     * set them in the original.
139     */

140    public InputHandler copy()
141    {
142       return new DefaultInputHandler(this);
143    }
144
145    /**
146     * Handle a key pressed event. This will look up the binding for
147     * the key stroke and execute it.
148     */

149    public void keyPressed(KeyEvent evt)
150    {
151       int keyCode = evt.getKeyCode();
152       int modifiers = evt.getModifiers();
153
154       if(keyCode == KeyEvent.VK_CONTROL ||
155          keyCode == KeyEvent.VK_SHIFT ||
156          keyCode == KeyEvent.VK_ALT ||
157          keyCode == KeyEvent.VK_META)
158          return;
159
160       if((modifiers & ~KeyEvent.SHIFT_MASK) != 0
161          || evt.isActionKey()
162          || keyCode == KeyEvent.VK_BACK_SPACE
163          || keyCode == KeyEvent.VK_DELETE
164          || keyCode == KeyEvent.VK_ENTER
165          || keyCode == KeyEvent.VK_TAB
166          || keyCode == KeyEvent.VK_ESCAPE)
167       {
168          if(grabAction != null)
169          {
170             handleGrabAction(evt);
171             return;
172          }
173
174          KeyStroke JavaDoc keyStroke = KeyStroke.getKeyStroke(keyCode,
175             modifiers);
176          Object JavaDoc o = currentBindings.get(keyStroke);
177          if(o == null)
178          {
179             // Don't beep if the user presses some
180
// key we don't know about unless a
181
// prefix is active. Otherwise it will
182
// beep when caps lock is pressed, etc.
183
if(currentBindings != bindings)
184             {
185                Toolkit.getDefaultToolkit().beep();
186                // F10 should be passed on, but C+e F10
187
// shouldn't
188
repeatCount = 0;
189                repeat = false;
190                evt.consume();
191             }
192             currentBindings = bindings;
193             return;
194          }
195          else if(o instanceof ActionListener)
196          {
197             currentBindings = bindings;
198
199             executeAction(((ActionListener)o),
200                evt.getSource(),null);
201
202             evt.consume();
203             return;
204          }
205          else if(o instanceof Hashtable JavaDoc)
206          {
207             currentBindings = (Hashtable JavaDoc)o;
208             evt.consume();
209             return;
210          }
211       }
212    }
213
214    /**
215     * Handle a key typed event. This inserts the key into the text area.
216     */

217    public void keyTyped(KeyEvent evt)
218    {
219       int modifiers = evt.getModifiers();
220       char c = evt.getKeyChar();
221       if(c != KeyEvent.CHAR_UNDEFINED &&
222          (modifiers & KeyEvent.ALT_MASK) == 0)
223       {
224          if(c >= 0x20 && c != 0x7f)
225          {
226             KeyStroke JavaDoc keyStroke = KeyStroke.getKeyStroke(
227                Character.toUpperCase(c));
228             Object JavaDoc o = currentBindings.get(keyStroke);
229
230             if(o instanceof Hashtable JavaDoc)
231             {
232                currentBindings = (Hashtable JavaDoc)o;
233                return;
234             }
235             else if(o instanceof ActionListener)
236             {
237                currentBindings = bindings;
238                executeAction((ActionListener)o,
239                   evt.getSource(),
240                   String.valueOf(c));
241                return;
242             }
243
244             currentBindings = bindings;
245
246             if(grabAction != null)
247             {
248                handleGrabAction(evt);
249                return;
250             }
251
252             // 0-9 adds another 'digit' to the repeat number
253
if(repeat && Character.isDigit(c))
254             {
255                repeatCount *= 10;
256                repeatCount += (c - '0');
257                return;
258             }
259
260             executeAction(INSERT_CHAR,evt.getSource(),
261                String.valueOf(evt.getKeyChar()));
262
263             repeatCount = 0;
264             repeat = false;
265          }
266       }
267    }
268
269    /**
270     * Converts a string to a keystroke. The string should be of the
271     * form <i>modifiers</i>+<i>shortcut</i> where <i>modifiers</i>
272     * is any combination of A for Alt, C for Control, S for Shift
273     * or M for Meta, and <i>shortcut</i> is either a single character,
274     * or a keycode name from the <code>KeyEvent</code> class, without
275     * the <code>VK_</code> prefix.
276     * @param keyStroke A string description of the key stroke
277     */

278    public static KeyStroke JavaDoc parseKeyStroke(String JavaDoc keyStroke)
279    {
280       if(keyStroke == null)
281          return null;
282       int modifiers = 0;
283       int index = keyStroke.indexOf('+');
284       if(index != -1)
285       {
286          for(int i = 0; i < index; i++)
287          {
288             switch(Character.toUpperCase(keyStroke
289                .charAt(i)))
290             {
291             case 'A':
292                modifiers |= InputEvent.ALT_MASK;
293                break;
294             case 'C':
295                modifiers |= InputEvent.CTRL_MASK;
296                break;
297             case 'M':
298                modifiers |= InputEvent.META_MASK;
299                break;
300             case 'S':
301                modifiers |= InputEvent.SHIFT_MASK;
302                break;
303             }
304          }
305       }
306       String JavaDoc key = keyStroke.substring(index + 1);
307       if(key.length() == 1)
308       {
309          char ch = Character.toUpperCase(key.charAt(0));
310          if(modifiers == 0)
311             return KeyStroke.getKeyStroke(ch);
312          else
313             return KeyStroke.getKeyStroke(ch,modifiers);
314       }
315       else if(key.length() == 0)
316       {
317          System.err.println("Invalid key stroke: " + keyStroke);
318          return null;
319       }
320       else
321       {
322          int ch;
323
324          try
325          {
326             ch = KeyEvent.class.getField("VK_".concat(key))
327                .getInt(null);
328          }
329          catch(Exception JavaDoc e)
330          {
331             System.err.println("Invalid key stroke: "
332                + keyStroke);
333             return null;
334          }
335
336          return KeyStroke.getKeyStroke(ch,modifiers);
337       }
338    }
339
340    // private members
341
private Hashtable JavaDoc bindings;
342    private Hashtable JavaDoc currentBindings;
343
344    private DefaultInputHandler(DefaultInputHandler copy)
345    {
346       bindings = currentBindings = copy.bindings;
347    }
348 }
349
Popular Tags