1
2
3
4
5
6
7
8
9 package com.ochafik.swing.syntaxcoloring;
10
11 import java.awt.Toolkit;
12 import java.awt.event.ActionListener;
13 import java.awt.event.InputEvent;
14 import java.awt.event.KeyEvent;
15 import java.util.Hashtable;
16 import java.util.StringTokenizer;
17
18 import javax.swing.KeyStroke;
19
20
21
22
23
24
25
26 public class DefaultInputHandler extends InputHandler
27 {
28
29
30
31 public DefaultInputHandler()
32 {
33 bindings = currentBindings = new Hashtable();
34 }
35
36
37
38
39 public void addDefaultKeyBindings()
40 {
41 addKeyBinding("C+C",COPY);
42 addKeyBinding("C+X",CUT);
43 addKeyBinding("C+V",PASTE);
44
45 addKeyBinding("BACK_SPACE",BACKSPACE);
46 addKeyBinding("C+BACK_SPACE",BACKSPACE_WORD);
47 addKeyBinding("DELETE",DELETE);
48 addKeyBinding("C+DELETE",DELETE_WORD);
49
50 addKeyBinding("ENTER",INSERT_BREAK);
51 addKeyBinding("TAB",INSERT_TAB);
52 addKeyBinding("S+TAB",REMOVE_TAB);
53 addKeyBinding("C+A",SELECT_ALL);
54
55 addKeyBinding("INSERT",OVERWRITE);
56 addKeyBinding("C+\\",TOGGLE_RECT);
57
58 addKeyBinding("HOME",HOME);
59 addKeyBinding("END",END);
60 addKeyBinding("S+HOME",SELECT_HOME);
61 addKeyBinding("S+END",SELECT_END);
62 addKeyBinding("C+HOME",DOCUMENT_HOME);
63 addKeyBinding("C+END",DOCUMENT_END);
64 addKeyBinding("CS+HOME",SELECT_DOC_HOME);
65 addKeyBinding("CS+END",SELECT_DOC_END);
66
67 addKeyBinding("PAGE_UP",PREV_PAGE);
68 addKeyBinding("PAGE_DOWN",NEXT_PAGE);
69 addKeyBinding("S+PAGE_UP",SELECT_PREV_PAGE);
70 addKeyBinding("S+PAGE_DOWN",SELECT_NEXT_PAGE);
71
72 addKeyBinding("LEFT",PREV_CHAR);
73 addKeyBinding("S+LEFT",SELECT_PREV_CHAR);
74 addKeyBinding("C+LEFT",PREV_WORD);
75 addKeyBinding("CS+LEFT",SELECT_PREV_WORD);
76 addKeyBinding("RIGHT",NEXT_CHAR);
77 addKeyBinding("S+RIGHT",SELECT_NEXT_CHAR);
78 addKeyBinding("C+RIGHT",NEXT_WORD);
79 addKeyBinding("CS+RIGHT",SELECT_NEXT_WORD);
80 addKeyBinding("UP",PREV_LINE);
81 addKeyBinding("S+UP",SELECT_PREV_LINE);
82 addKeyBinding("DOWN",NEXT_LINE);
83 addKeyBinding("S+DOWN",SELECT_NEXT_LINE);
84
85 addKeyBinding("C+ENTER",REPEAT);
86 }
87
88
89
90
91
92
93
94
95
96
97 public void addKeyBinding(String keyBinding, ActionListener action)
98 {
99 Hashtable current = bindings;
100
101 StringTokenizer st = new StringTokenizer(keyBinding);
102 while(st.hasMoreTokens())
103 {
104 KeyStroke keyStroke = parseKeyStroke(st.nextToken());
105 if(keyStroke == null)
106 return;
107
108 if(st.hasMoreTokens())
109 {
110 Object o = current.get(keyStroke);
111 if(o instanceof Hashtable)
112 current = (Hashtable)o;
113 else
114 {
115 o = new Hashtable();
116 current.put(keyStroke,o);
117 current = (Hashtable)o;
118 }
119 }
120 else
121 current.put(keyStroke,action);
122 }
123 }
124 public void addKeyBinding(KeyStroke keyStroke, ActionListener action) {
125 Hashtable current = bindings;
126 current.put(keyStroke,action);
127 }
128
129
130
131
132
133
134 public void removeKeyBinding(String keyBinding)
135 {
136 throw new InternalError("Not yet implemented");
137 }
138
139
140
141
142 public void removeAllKeyBindings()
143 {
144 bindings.clear();
145 }
146
147
148
149
150
151
152 public InputHandler copy()
153 {
154 return new DefaultInputHandler(this);
155 }
156
157
158
159
160
161 public void keyPressed(KeyEvent evt)
162 {
163 int keyCode = evt.getKeyCode();
164 int modifiers = evt.getModifiers();
165
166 if(keyCode == KeyEvent.VK_CONTROL ||
167 keyCode == KeyEvent.VK_SHIFT ||
168 keyCode == KeyEvent.VK_ALT ||
169 keyCode == KeyEvent.VK_META)
170 return;
171
172 if((modifiers & ~KeyEvent.SHIFT_MASK) != 0
173 || evt.isActionKey()
174 || keyCode == KeyEvent.VK_BACK_SPACE
175 || keyCode == KeyEvent.VK_DELETE
176 || keyCode == KeyEvent.VK_ENTER
177 || keyCode == KeyEvent.VK_TAB
178 || keyCode == KeyEvent.VK_ESCAPE)
179 {
180 if(grabAction != null)
181 {
182 handleGrabAction(evt);
183 return;
184 }
185
186 KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode,
187 modifiers);
188 Object o = currentBindings.get(keyStroke);
189 if(o == null)
190 {
191
192
193
194
195 if(currentBindings != bindings)
196 {
197 Toolkit.getDefaultToolkit().beep();
198
199
200 repeatCount = 0;
201 repeat = false;
202 evt.consume();
203 }
204 currentBindings = bindings;
205 return;
206 }
207 else if(o instanceof ActionListener)
208 {
209 currentBindings = bindings;
210
211 executeAction(((ActionListener)o),
212 evt.getSource(),null);
213
214 evt.consume();
215 return;
216 }
217 else if(o instanceof Hashtable)
218 {
219 currentBindings = (Hashtable)o;
220 evt.consume();
221 return;
222 }
223 }
224 }
225
226
227
228
229 public void keyTyped(KeyEvent evt)
230 {
231 int modifiers = evt.getModifiers();
232 char c = evt.getKeyChar();
233 if(c != KeyEvent.CHAR_UNDEFINED)
234
235 {
236 if(c >= 0x20 && c != 0x7f)
237 {
238 KeyStroke keyStroke = KeyStroke.getKeyStroke(
239 Character.toUpperCase(c));
240 Object o = currentBindings.get(keyStroke);
241
242 if(o instanceof Hashtable)
243 {
244 currentBindings = (Hashtable)o;
245 return;
246 }
247 else if(o instanceof ActionListener)
248 {
249 currentBindings = bindings;
250 executeAction((ActionListener)o,
251 evt.getSource(),
252 String.valueOf(c));
253 return;
254 }
255
256 currentBindings = bindings;
257
258 if(grabAction != null)
259 {
260 handleGrabAction(evt);
261 return;
262 }
263
264
265 if(repeat && Character.isDigit(c))
266 {
267 repeatCount *= 10;
268 repeatCount += (c - '0');
269 return;
270 }
271
272 executeAction(INSERT_CHAR,evt.getSource(),
273 String.valueOf(evt.getKeyChar()));
274
275 repeatCount = 0;
276 repeat = false;
277 }
278 }
279 }
280
281
282
283
284
285
286
287
288
289
290 public static KeyStroke parseKeyStroke(String keyStroke)
291 {
292 if(keyStroke == null)
293 return null;
294 int modifiers = 0;
295 int index = keyStroke.indexOf('+');
296 if(index != -1)
297 {
298 for(int i = 0; i < index; i++)
299 {
300 switch(Character.toUpperCase(keyStroke
301 .charAt(i)))
302 {
303 case 'A':
304 modifiers |= InputEvent.ALT_MASK;
305 break;
306 case 'C':
307 modifiers |= InputEvent.CTRL_MASK;
308 break;
309 case 'M':
310 modifiers |= InputEvent.META_MASK;
311 break;
312 case 'S':
313 modifiers |= InputEvent.SHIFT_MASK;
314 break;
315 }
316 }
317 }
318 String key = keyStroke.substring(index + 1);
319 if(key.length() == 1)
320 {
321 char ch = Character.toUpperCase(key.charAt(0));
322 if(modifiers == 0)
323 return KeyStroke.getKeyStroke(ch);
324 else
325 return KeyStroke.getKeyStroke(ch,modifiers);
326 }
327 else if(key.length() == 0)
328 {
329 System.err.println("Invalid key stroke: " + keyStroke);
330 return null;
331 }
332 else
333 {
334 int ch;
335
336 try
337 {
338 ch = KeyEvent.class.getField("VK_".concat(key))
339 .getInt(null);
340 }
341 catch(Exception e)
342 {
343 System.err.println("Invalid key stroke: "
344 + keyStroke);
345 return null;
346 }
347
348 return KeyStroke.getKeyStroke(ch,modifiers);
349 }
350 }
351
352
353 private Hashtable bindings;
354 private Hashtable currentBindings;
355
356 private DefaultInputHandler(DefaultInputHandler copy)
357 {
358 bindings = currentBindings = copy.bindings;
359 }
360 }