svn-gvsig-desktop / tags / v1_1_Build_1000 / libraries / libIverUtiles / src / com / iver / utiles / console / jedit / InputHandler.java @ 11885
History | View | Annotate | Download (26.3 KB)
1 | 4890 | caballero | package com.iver.utiles.console.jedit; |
---|---|---|---|
2 | /*
|
||
3 | * InputHandler.java - Manages key bindings and executes actions
|
||
4 | * Copyright (C) 1999 Slava Pestov
|
||
5 | *
|
||
6 | * You may use and modify this package for any purpose. Redistribution is
|
||
7 | * permitted, in both source and binary form, provided that this notice
|
||
8 | * remains intact in all source distributions of this package.
|
||
9 | */
|
||
10 | |||
11 | import java.awt.Component; |
||
12 | 8765 | jjdelcerro | import java.awt.event.ActionEvent; |
13 | import java.awt.event.ActionListener; |
||
14 | import java.awt.event.KeyAdapter; |
||
15 | import java.awt.event.KeyEvent; |
||
16 | import java.util.Enumeration; |
||
17 | import java.util.EventObject; |
||
18 | import java.util.Hashtable; |
||
19 | 4890 | caballero | |
20 | 8765 | jjdelcerro | import javax.swing.JPopupMenu; |
21 | import javax.swing.text.BadLocationException; |
||
22 | |||
23 | 4890 | caballero | /**
|
24 | * An input handler converts the user's key strokes into concrete actions.
|
||
25 | * It also takes care of macro recording and action repetition.<p>
|
||
26 | *
|
||
27 | * This class provides all the necessary support code for an input
|
||
28 | * handler, but doesn't actually do any key binding logic. It is up
|
||
29 | * to the implementations of this class to do so.
|
||
30 | *
|
||
31 | * @author Slava Pestov
|
||
32 | * @version $Id$
|
||
33 | * @see org.gjt.sp.jedit.textarea.DefaultInputHandler
|
||
34 | */
|
||
35 | public abstract class InputHandler extends KeyAdapter |
||
36 | { |
||
37 | /**
|
||
38 | * If this client property is set to Boolean.TRUE on the text area,
|
||
39 | * the home/end keys will support 'smart' BRIEF-like behaviour
|
||
40 | * (one press = start/end of line, two presses = start/end of
|
||
41 | * viewscreen, three presses = start/end of document). By default,
|
||
42 | * this property is not set.
|
||
43 | */
|
||
44 | public static final String SMART_HOME_END_PROPERTY = "InputHandler.homeEnd"; |
||
45 | |||
46 | public static final ActionListener BACKSPACE = new backspace(); |
||
47 | public static final ActionListener BACKSPACE_WORD = new backspace_word(); |
||
48 | public static final ActionListener DELETE = new delete(); |
||
49 | public static final ActionListener DELETE_WORD = new delete_word(); |
||
50 | public static final ActionListener END = new end(false); |
||
51 | public static final ActionListener DOCUMENT_END = new document_end(false); |
||
52 | public static final ActionListener SELECT_END = new end(true); |
||
53 | public static final ActionListener SELECT_DOC_END = new document_end(true); |
||
54 | public static final ActionListener INSERT_BREAK = new insert_break(); |
||
55 | public static final ActionListener INSERT_TAB = new insert_tab(); |
||
56 | public static final ActionListener HOME = new home(false); |
||
57 | public static final ActionListener DOCUMENT_HOME = new document_home(false); |
||
58 | public static final ActionListener SELECT_HOME = new home(true); |
||
59 | public static final ActionListener SELECT_DOC_HOME = new document_home(true); |
||
60 | public static final ActionListener NEXT_CHAR = new next_char(false); |
||
61 | public static final ActionListener NEXT_LINE = new next_line(false); |
||
62 | public static final ActionListener NEXT_PAGE = new next_page(false); |
||
63 | public static final ActionListener NEXT_WORD = new next_word(false); |
||
64 | public static final ActionListener SELECT_NEXT_CHAR = new next_char(true); |
||
65 | public static final ActionListener SELECT_NEXT_LINE = new next_line(true); |
||
66 | public static final ActionListener SELECT_NEXT_PAGE = new next_page(true); |
||
67 | public static final ActionListener SELECT_NEXT_WORD = new next_word(true); |
||
68 | public static final ActionListener OVERWRITE = new overwrite(); |
||
69 | public static final ActionListener PREV_CHAR = new prev_char(false); |
||
70 | public static final ActionListener PREV_LINE = new prev_line(false); |
||
71 | public static final ActionListener PREV_PAGE = new prev_page(false); |
||
72 | public static final ActionListener PREV_WORD = new prev_word(false); |
||
73 | public static final ActionListener SELECT_PREV_CHAR = new prev_char(true); |
||
74 | public static final ActionListener SELECT_PREV_LINE = new prev_line(true); |
||
75 | public static final ActionListener SELECT_PREV_PAGE = new prev_page(true); |
||
76 | public static final ActionListener SELECT_PREV_WORD = new prev_word(true); |
||
77 | public static final ActionListener REPEAT = new repeat(); |
||
78 | public static final ActionListener TOGGLE_RECT = new toggle_rect(); |
||
79 | |||
80 | // Default action
|
||
81 | public static final ActionListener INSERT_CHAR = new insert_char(); |
||
82 | |||
83 | private static Hashtable actions; |
||
84 | |||
85 | static
|
||
86 | { |
||
87 | actions = new Hashtable(); |
||
88 | actions.put("backspace",BACKSPACE);
|
||
89 | actions.put("backspace-word",BACKSPACE_WORD);
|
||
90 | actions.put("delete",DELETE);
|
||
91 | actions.put("delete-word",DELETE_WORD);
|
||
92 | actions.put("end",END);
|
||
93 | actions.put("select-end",SELECT_END);
|
||
94 | actions.put("document-end",DOCUMENT_END);
|
||
95 | actions.put("select-doc-end",SELECT_DOC_END);
|
||
96 | actions.put("insert-break",INSERT_BREAK);
|
||
97 | actions.put("insert-tab",INSERT_TAB);
|
||
98 | actions.put("home",HOME);
|
||
99 | actions.put("select-home",SELECT_HOME);
|
||
100 | actions.put("document-home",DOCUMENT_HOME);
|
||
101 | actions.put("select-doc-home",SELECT_DOC_HOME);
|
||
102 | actions.put("next-char",NEXT_CHAR);
|
||
103 | actions.put("next-line",NEXT_LINE);
|
||
104 | actions.put("next-page",NEXT_PAGE);
|
||
105 | actions.put("next-word",NEXT_WORD);
|
||
106 | actions.put("select-next-char",SELECT_NEXT_CHAR);
|
||
107 | actions.put("select-next-line",SELECT_NEXT_LINE);
|
||
108 | actions.put("select-next-page",SELECT_NEXT_PAGE);
|
||
109 | actions.put("select-next-word",SELECT_NEXT_WORD);
|
||
110 | actions.put("overwrite",OVERWRITE);
|
||
111 | actions.put("prev-char",PREV_CHAR);
|
||
112 | actions.put("prev-line",PREV_LINE);
|
||
113 | actions.put("prev-page",PREV_PAGE);
|
||
114 | actions.put("prev-word",PREV_WORD);
|
||
115 | actions.put("select-prev-char",SELECT_PREV_CHAR);
|
||
116 | actions.put("select-prev-line",SELECT_PREV_LINE);
|
||
117 | actions.put("select-prev-page",SELECT_PREV_PAGE);
|
||
118 | actions.put("select-prev-word",SELECT_PREV_WORD);
|
||
119 | actions.put("repeat",REPEAT);
|
||
120 | actions.put("toggle-rect",TOGGLE_RECT);
|
||
121 | actions.put("insert-char",INSERT_CHAR);
|
||
122 | } |
||
123 | |||
124 | /**
|
||
125 | * Returns a named text area action.
|
||
126 | * @param name The action name
|
||
127 | */
|
||
128 | public static ActionListener getAction(String name) |
||
129 | { |
||
130 | return (ActionListener)actions.get(name); |
||
131 | } |
||
132 | |||
133 | /**
|
||
134 | * Returns the name of the specified text area action.
|
||
135 | * @param listener The action
|
||
136 | */
|
||
137 | public static String getActionName(ActionListener listener) |
||
138 | { |
||
139 | 8765 | jjdelcerro | Enumeration enumeration = getActions();
|
140 | while(enumeration.hasMoreElements())
|
||
141 | 4890 | caballero | { |
142 | 8765 | jjdelcerro | String name = (String)enumeration.nextElement(); |
143 | 4890 | caballero | ActionListener _listener = getAction(name);
|
144 | if(_listener == listener)
|
||
145 | return name;
|
||
146 | } |
||
147 | return null; |
||
148 | } |
||
149 | |||
150 | /**
|
||
151 | * Returns an enumeration of all available actions.
|
||
152 | */
|
||
153 | public static Enumeration getActions() |
||
154 | { |
||
155 | return actions.keys();
|
||
156 | } |
||
157 | |||
158 | /**
|
||
159 | * Adds the default key bindings to this input handler.
|
||
160 | * This should not be called in the constructor of this
|
||
161 | * input handler, because applications might load the
|
||
162 | * key bindings from a file, etc.
|
||
163 | */
|
||
164 | public abstract void addDefaultKeyBindings(); |
||
165 | |||
166 | /**
|
||
167 | * Adds a key binding to this input handler.
|
||
168 | * @param keyBinding The key binding (the format of this is
|
||
169 | * input-handler specific)
|
||
170 | * @param action The action
|
||
171 | */
|
||
172 | public abstract void addKeyBinding(String keyBinding, ActionListener action); |
||
173 | |||
174 | /**
|
||
175 | * Removes a key binding from this input handler.
|
||
176 | * @param keyBinding The key binding
|
||
177 | */
|
||
178 | public abstract void removeKeyBinding(String keyBinding); |
||
179 | |||
180 | /**
|
||
181 | * Removes all key bindings from this input handler.
|
||
182 | */
|
||
183 | public abstract void removeAllKeyBindings(); |
||
184 | |||
185 | /**
|
||
186 | * Grabs the next key typed event and invokes the specified
|
||
187 | * action with the key as a the action command.
|
||
188 | * @param action The action
|
||
189 | */
|
||
190 | public void grabNextKeyStroke(ActionListener listener) |
||
191 | { |
||
192 | grabAction = listener; |
||
193 | } |
||
194 | |||
195 | /**
|
||
196 | * Returns if repeating is enabled. When repeating is enabled,
|
||
197 | * actions will be executed multiple times. This is usually
|
||
198 | * invoked with a special key stroke in the input handler.
|
||
199 | */
|
||
200 | public boolean isRepeatEnabled() |
||
201 | { |
||
202 | return repeat;
|
||
203 | } |
||
204 | |||
205 | /**
|
||
206 | * Enables repeating. When repeating is enabled, actions will be
|
||
207 | * executed multiple times. Once repeating is enabled, the input
|
||
208 | * handler should read a number from the keyboard.
|
||
209 | */
|
||
210 | public void setRepeatEnabled(boolean repeat) |
||
211 | { |
||
212 | this.repeat = repeat;
|
||
213 | } |
||
214 | |||
215 | /**
|
||
216 | * Returns the number of times the next action will be repeated.
|
||
217 | */
|
||
218 | public int getRepeatCount() |
||
219 | { |
||
220 | return (repeat ? Math.max(1,repeatCount) : 1); |
||
221 | } |
||
222 | |||
223 | /**
|
||
224 | * Sets the number of times the next action will be repeated.
|
||
225 | * @param repeatCount The repeat count
|
||
226 | */
|
||
227 | public void setRepeatCount(int repeatCount) |
||
228 | { |
||
229 | this.repeatCount = repeatCount;
|
||
230 | } |
||
231 | |||
232 | /**
|
||
233 | * Returns the macro recorder. If this is non-null, all executed
|
||
234 | * actions should be forwarded to the recorder.
|
||
235 | */
|
||
236 | public InputHandler.MacroRecorder getMacroRecorder()
|
||
237 | { |
||
238 | return recorder;
|
||
239 | } |
||
240 | |||
241 | /**
|
||
242 | * Sets the macro recorder. If this is non-null, all executed
|
||
243 | * actions should be forwarded to the recorder.
|
||
244 | * @param recorder The macro recorder
|
||
245 | */
|
||
246 | public void setMacroRecorder(InputHandler.MacroRecorder recorder) |
||
247 | { |
||
248 | this.recorder = recorder;
|
||
249 | } |
||
250 | |||
251 | /**
|
||
252 | * Returns a copy of this input handler that shares the same
|
||
253 | * key bindings. Setting key bindings in the copy will also
|
||
254 | * set them in the original.
|
||
255 | */
|
||
256 | public abstract InputHandler copy(); |
||
257 | |||
258 | /**
|
||
259 | * Executes the specified action, repeating and recording it as
|
||
260 | * necessary.
|
||
261 | * @param listener The action listener
|
||
262 | * @param source The event source
|
||
263 | * @param actionCommand The action command
|
||
264 | */
|
||
265 | public void executeAction(ActionListener listener, Object source, |
||
266 | String actionCommand)
|
||
267 | { |
||
268 | // create event
|
||
269 | ActionEvent evt = new ActionEvent(source, |
||
270 | ActionEvent.ACTION_PERFORMED,
|
||
271 | actionCommand); |
||
272 | |||
273 | // don't do anything if the action is a wrapper
|
||
274 | // (like EditAction.Wrapper)
|
||
275 | if(listener instanceof Wrapper) |
||
276 | { |
||
277 | listener.actionPerformed(evt); |
||
278 | return;
|
||
279 | } |
||
280 | |||
281 | // remember old values, in case action changes them
|
||
282 | boolean _repeat = repeat;
|
||
283 | int _repeatCount = getRepeatCount();
|
||
284 | |||
285 | // execute the action
|
||
286 | if(listener instanceof InputHandler.NonRepeatable) |
||
287 | listener.actionPerformed(evt); |
||
288 | else
|
||
289 | { |
||
290 | for(int i = 0; i < Math.max(1,repeatCount); i++) |
||
291 | listener.actionPerformed(evt); |
||
292 | } |
||
293 | |||
294 | // do recording. Notice that we do no recording whatsoever
|
||
295 | // for actions that grab keys
|
||
296 | if(grabAction == null) |
||
297 | { |
||
298 | if(recorder != null) |
||
299 | { |
||
300 | if(!(listener instanceof InputHandler.NonRecordable)) |
||
301 | { |
||
302 | if(_repeatCount != 1) |
||
303 | recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount));
|
||
304 | |||
305 | recorder.actionPerformed(listener,actionCommand); |
||
306 | } |
||
307 | } |
||
308 | |||
309 | // If repeat was true originally, clear it
|
||
310 | // Otherwise it might have been set by the action, etc
|
||
311 | if(_repeat)
|
||
312 | { |
||
313 | repeat = false;
|
||
314 | repeatCount = 0;
|
||
315 | } |
||
316 | } |
||
317 | } |
||
318 | |||
319 | /**
|
||
320 | * Returns the text area that fired the specified event.
|
||
321 | * @param evt The event
|
||
322 | */
|
||
323 | public static JEditTextArea getTextArea(EventObject evt) |
||
324 | { |
||
325 | if(evt != null) |
||
326 | { |
||
327 | Object o = evt.getSource();
|
||
328 | if(o instanceof Component) |
||
329 | { |
||
330 | // find the parent text area
|
||
331 | Component c = (Component)o; |
||
332 | for(;;)
|
||
333 | { |
||
334 | if(c instanceof JEditTextArea) |
||
335 | return (JEditTextArea)c;
|
||
336 | else if(c == null) |
||
337 | break;
|
||
338 | if(c instanceof JPopupMenu) |
||
339 | c = ((JPopupMenu)c)
|
||
340 | .getInvoker(); |
||
341 | else
|
||
342 | c = c.getParent(); |
||
343 | } |
||
344 | } |
||
345 | } |
||
346 | |||
347 | // this shouldn't happen
|
||
348 | System.err.println("BUG: getTextArea() returning null"); |
||
349 | System.err.println("Report this to Slava Pestov <sp@gjt.org>"); |
||
350 | return null; |
||
351 | } |
||
352 | |||
353 | // protected members
|
||
354 | |||
355 | /**
|
||
356 | * If a key is being grabbed, this method should be called with
|
||
357 | * the appropriate key event. It executes the grab action with
|
||
358 | * the typed character as the parameter.
|
||
359 | */
|
||
360 | protected void handleGrabAction(KeyEvent evt) |
||
361 | { |
||
362 | // Clear it *before* it is executed so that executeAction()
|
||
363 | // resets the repeat count
|
||
364 | ActionListener _grabAction = grabAction;
|
||
365 | grabAction = null;
|
||
366 | executeAction(_grabAction,evt.getSource(), |
||
367 | String.valueOf(evt.getKeyChar()));
|
||
368 | } |
||
369 | |||
370 | // protected members
|
||
371 | protected ActionListener grabAction; |
||
372 | protected boolean repeat; |
||
373 | protected int repeatCount; |
||
374 | protected InputHandler.MacroRecorder recorder;
|
||
375 | |||
376 | /**
|
||
377 | * If an action implements this interface, it should not be repeated.
|
||
378 | * Instead, it will handle the repetition itself.
|
||
379 | */
|
||
380 | public interface NonRepeatable {} |
||
381 | |||
382 | /**
|
||
383 | * If an action implements this interface, it should not be recorded
|
||
384 | * by the macro recorder. Instead, it will do its own recording.
|
||
385 | */
|
||
386 | public interface NonRecordable {} |
||
387 | |||
388 | /**
|
||
389 | * For use by EditAction.Wrapper only.
|
||
390 | * @since jEdit 2.2final
|
||
391 | */
|
||
392 | public interface Wrapper {} |
||
393 | |||
394 | /**
|
||
395 | * Macro recorder.
|
||
396 | */
|
||
397 | public interface MacroRecorder |
||
398 | { |
||
399 | void actionPerformed(ActionListener listener, |
||
400 | String actionCommand);
|
||
401 | } |
||
402 | |||
403 | public static class backspace implements ActionListener |
||
404 | { |
||
405 | public void actionPerformed(ActionEvent evt) |
||
406 | { |
||
407 | JEditTextArea textArea = getTextArea(evt); |
||
408 | |||
409 | if(!textArea.isEditable())
|
||
410 | { |
||
411 | textArea.getToolkit().beep(); |
||
412 | return;
|
||
413 | } |
||
414 | |||
415 | if(textArea.getSelectionStart()
|
||
416 | != textArea.getSelectionEnd()) |
||
417 | { |
||
418 | textArea.setSelectedText("");
|
||
419 | } |
||
420 | else
|
||
421 | { |
||
422 | int caret = textArea.getCaretPosition();
|
||
423 | if(caret == 0) |
||
424 | { |
||
425 | textArea.getToolkit().beep(); |
||
426 | return;
|
||
427 | } |
||
428 | try
|
||
429 | { |
||
430 | textArea.getDocument().remove(caret - 1,1); |
||
431 | } |
||
432 | catch(BadLocationException bl) |
||
433 | { |
||
434 | bl.printStackTrace(); |
||
435 | } |
||
436 | } |
||
437 | } |
||
438 | } |
||
439 | |||
440 | public static class backspace_word implements ActionListener |
||
441 | { |
||
442 | public void actionPerformed(ActionEvent evt) |
||
443 | { |
||
444 | JEditTextArea textArea = getTextArea(evt); |
||
445 | int start = textArea.getSelectionStart();
|
||
446 | if(start != textArea.getSelectionEnd())
|
||
447 | { |
||
448 | textArea.setSelectedText("");
|
||
449 | } |
||
450 | |||
451 | int line = textArea.getCaretLine();
|
||
452 | int lineStart = textArea.getLineStartOffset(line);
|
||
453 | int caret = start - lineStart;
|
||
454 | |||
455 | String lineText = textArea.getLineText(textArea
|
||
456 | .getCaretLine()); |
||
457 | |||
458 | if(caret == 0) |
||
459 | { |
||
460 | if(lineStart == 0) |
||
461 | { |
||
462 | textArea.getToolkit().beep(); |
||
463 | return;
|
||
464 | } |
||
465 | caret--; |
||
466 | } |
||
467 | else
|
||
468 | { |
||
469 | String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); |
||
470 | caret = TextUtilities.findWordStart(lineText,caret,noWordSep); |
||
471 | } |
||
472 | |||
473 | try
|
||
474 | { |
||
475 | textArea.getDocument().remove( |
||
476 | caret + lineStart, |
||
477 | start - (caret + lineStart)); |
||
478 | } |
||
479 | catch(BadLocationException bl) |
||
480 | { |
||
481 | bl.printStackTrace(); |
||
482 | } |
||
483 | } |
||
484 | } |
||
485 | |||
486 | public static class delete implements ActionListener |
||
487 | { |
||
488 | public void actionPerformed(ActionEvent evt) |
||
489 | { |
||
490 | JEditTextArea textArea = getTextArea(evt); |
||
491 | |||
492 | if(!textArea.isEditable())
|
||
493 | { |
||
494 | textArea.getToolkit().beep(); |
||
495 | return;
|
||
496 | } |
||
497 | |||
498 | if(textArea.getSelectionStart()
|
||
499 | != textArea.getSelectionEnd()) |
||
500 | { |
||
501 | textArea.setSelectedText("");
|
||
502 | } |
||
503 | else
|
||
504 | { |
||
505 | int caret = textArea.getCaretPosition();
|
||
506 | if(caret == textArea.getDocumentLength())
|
||
507 | { |
||
508 | textArea.getToolkit().beep(); |
||
509 | return;
|
||
510 | } |
||
511 | try
|
||
512 | { |
||
513 | textArea.getDocument().remove(caret,1);
|
||
514 | } |
||
515 | catch(BadLocationException bl) |
||
516 | { |
||
517 | bl.printStackTrace(); |
||
518 | } |
||
519 | } |
||
520 | } |
||
521 | } |
||
522 | |||
523 | public static class delete_word implements ActionListener |
||
524 | { |
||
525 | public void actionPerformed(ActionEvent evt) |
||
526 | { |
||
527 | JEditTextArea textArea = getTextArea(evt); |
||
528 | int start = textArea.getSelectionStart();
|
||
529 | if(start != textArea.getSelectionEnd())
|
||
530 | { |
||
531 | textArea.setSelectedText("");
|
||
532 | } |
||
533 | |||
534 | int line = textArea.getCaretLine();
|
||
535 | int lineStart = textArea.getLineStartOffset(line);
|
||
536 | int caret = start - lineStart;
|
||
537 | |||
538 | String lineText = textArea.getLineText(textArea
|
||
539 | .getCaretLine()); |
||
540 | |||
541 | if(caret == lineText.length())
|
||
542 | { |
||
543 | if(lineStart + caret == textArea.getDocumentLength())
|
||
544 | { |
||
545 | textArea.getToolkit().beep(); |
||
546 | return;
|
||
547 | } |
||
548 | caret++; |
||
549 | } |
||
550 | else
|
||
551 | { |
||
552 | String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); |
||
553 | caret = TextUtilities.findWordEnd(lineText,caret,noWordSep); |
||
554 | } |
||
555 | |||
556 | try
|
||
557 | { |
||
558 | textArea.getDocument().remove(start, |
||
559 | (caret + lineStart) - start); |
||
560 | } |
||
561 | catch(BadLocationException bl) |
||
562 | { |
||
563 | bl.printStackTrace(); |
||
564 | } |
||
565 | } |
||
566 | } |
||
567 | |||
568 | public static class end implements ActionListener |
||
569 | { |
||
570 | private boolean select; |
||
571 | |||
572 | public end(boolean select) |
||
573 | { |
||
574 | this.select = select;
|
||
575 | } |
||
576 | |||
577 | public void actionPerformed(ActionEvent evt) |
||
578 | { |
||
579 | JEditTextArea textArea = getTextArea(evt); |
||
580 | |||
581 | int caret = textArea.getCaretPosition();
|
||
582 | |||
583 | int lastOfLine = textArea.getLineEndOffset(
|
||
584 | textArea.getCaretLine()) - 1;
|
||
585 | int lastVisibleLine = textArea.getFirstLine()
|
||
586 | + textArea.getVisibleLines(); |
||
587 | if(lastVisibleLine >= textArea.getLineCount())
|
||
588 | { |
||
589 | lastVisibleLine = Math.min(textArea.getLineCount() - 1, |
||
590 | lastVisibleLine); |
||
591 | } |
||
592 | else
|
||
593 | lastVisibleLine -= (textArea.getElectricScroll() + 1);
|
||
594 | |||
595 | int lastVisible = textArea.getLineEndOffset(lastVisibleLine) - 1; |
||
596 | int lastDocument = textArea.getDocumentLength();
|
||
597 | |||
598 | if(caret == lastDocument)
|
||
599 | { |
||
600 | textArea.getToolkit().beep(); |
||
601 | return;
|
||
602 | } |
||
603 | else if(!Boolean.TRUE.equals(textArea.getClientProperty( |
||
604 | SMART_HOME_END_PROPERTY))) |
||
605 | caret = lastOfLine; |
||
606 | else if(caret == lastVisible) |
||
607 | caret = lastDocument; |
||
608 | else if(caret == lastOfLine) |
||
609 | caret = lastVisible; |
||
610 | else
|
||
611 | caret = lastOfLine; |
||
612 | |||
613 | if(select)
|
||
614 | textArea.select(textArea.getMarkPosition(),caret); |
||
615 | else
|
||
616 | textArea.setCaretPosition(caret); |
||
617 | } |
||
618 | } |
||
619 | |||
620 | public static class document_end implements ActionListener |
||
621 | { |
||
622 | private boolean select; |
||
623 | |||
624 | public document_end(boolean select) |
||
625 | { |
||
626 | this.select = select;
|
||
627 | } |
||
628 | |||
629 | public void actionPerformed(ActionEvent evt) |
||
630 | { |
||
631 | JEditTextArea textArea = getTextArea(evt); |
||
632 | if(select)
|
||
633 | textArea.select(textArea.getMarkPosition(), |
||
634 | textArea.getDocumentLength()); |
||
635 | else
|
||
636 | textArea.setCaretPosition(textArea |
||
637 | .getDocumentLength()); |
||
638 | } |
||
639 | } |
||
640 | |||
641 | public static class home implements ActionListener |
||
642 | { |
||
643 | private boolean select; |
||
644 | |||
645 | public home(boolean select) |
||
646 | { |
||
647 | this.select = select;
|
||
648 | } |
||
649 | |||
650 | public void actionPerformed(ActionEvent evt) |
||
651 | { |
||
652 | JEditTextArea textArea = getTextArea(evt); |
||
653 | |||
654 | int caret = textArea.getCaretPosition();
|
||
655 | |||
656 | int firstLine = textArea.getFirstLine();
|
||
657 | |||
658 | int firstOfLine = textArea.getLineStartOffset(
|
||
659 | textArea.getCaretLine()); |
||
660 | int firstVisibleLine = (firstLine == 0 ? 0 : |
||
661 | firstLine + textArea.getElectricScroll()); |
||
662 | int firstVisible = textArea.getLineStartOffset(
|
||
663 | firstVisibleLine); |
||
664 | |||
665 | if(caret == 0) |
||
666 | { |
||
667 | textArea.getToolkit().beep(); |
||
668 | return;
|
||
669 | } |
||
670 | else if(!Boolean.TRUE.equals(textArea.getClientProperty( |
||
671 | SMART_HOME_END_PROPERTY))) |
||
672 | caret = firstOfLine; |
||
673 | else if(caret == firstVisible) |
||
674 | caret = 0;
|
||
675 | else if(caret == firstOfLine) |
||
676 | caret = firstVisible; |
||
677 | else
|
||
678 | caret = firstOfLine; |
||
679 | |||
680 | if(select)
|
||
681 | textArea.select(textArea.getMarkPosition(),caret); |
||
682 | else
|
||
683 | textArea.setCaretPosition(caret); |
||
684 | } |
||
685 | } |
||
686 | |||
687 | public static class document_home implements ActionListener |
||
688 | { |
||
689 | private boolean select; |
||
690 | |||
691 | public document_home(boolean select) |
||
692 | { |
||
693 | this.select = select;
|
||
694 | } |
||
695 | |||
696 | public void actionPerformed(ActionEvent evt) |
||
697 | { |
||
698 | JEditTextArea textArea = getTextArea(evt); |
||
699 | if(select)
|
||
700 | textArea.select(textArea.getMarkPosition(),0);
|
||
701 | else
|
||
702 | textArea.setCaretPosition(0);
|
||
703 | } |
||
704 | } |
||
705 | |||
706 | public static class insert_break implements ActionListener |
||
707 | { |
||
708 | public void actionPerformed(ActionEvent evt) |
||
709 | { |
||
710 | JEditTextArea textArea = getTextArea(evt); |
||
711 | |||
712 | if(!textArea.isEditable())
|
||
713 | { |
||
714 | textArea.getToolkit().beep(); |
||
715 | return;
|
||
716 | } |
||
717 | |||
718 | textArea.setSelectedText("\n");
|
||
719 | } |
||
720 | } |
||
721 | |||
722 | public static class insert_tab implements ActionListener |
||
723 | { |
||
724 | public void actionPerformed(ActionEvent evt) |
||
725 | { |
||
726 | JEditTextArea textArea = getTextArea(evt); |
||
727 | |||
728 | if(!textArea.isEditable())
|
||
729 | { |
||
730 | textArea.getToolkit().beep(); |
||
731 | return;
|
||
732 | } |
||
733 | |||
734 | textArea.overwriteSetSelectedText("\t");
|
||
735 | } |
||
736 | } |
||
737 | |||
738 | public static class next_char implements ActionListener |
||
739 | { |
||
740 | private boolean select; |
||
741 | |||
742 | public next_char(boolean select) |
||
743 | { |
||
744 | this.select = select;
|
||
745 | } |
||
746 | |||
747 | public void actionPerformed(ActionEvent evt) |
||
748 | { |
||
749 | JEditTextArea textArea = getTextArea(evt); |
||
750 | int caret = textArea.getCaretPosition();
|
||
751 | if(caret == textArea.getDocumentLength())
|
||
752 | { |
||
753 | textArea.getToolkit().beep(); |
||
754 | return;
|
||
755 | } |
||
756 | |||
757 | if(select)
|
||
758 | textArea.select(textArea.getMarkPosition(), |
||
759 | caret + 1);
|
||
760 | else
|
||
761 | textArea.setCaretPosition(caret + 1);
|
||
762 | } |
||
763 | } |
||
764 | |||
765 | public static class next_line implements ActionListener |
||
766 | { |
||
767 | private boolean select; |
||
768 | |||
769 | public next_line(boolean select) |
||
770 | { |
||
771 | this.select = select;
|
||
772 | } |
||
773 | |||
774 | public void actionPerformed(ActionEvent evt) |
||
775 | { |
||
776 | JEditTextArea textArea = getTextArea(evt); |
||
777 | int caret = textArea.getCaretPosition();
|
||
778 | int line = textArea.getCaretLine();
|
||
779 | |||
780 | if(line == textArea.getLineCount() - 1) |
||
781 | { |
||
782 | textArea.getToolkit().beep(); |
||
783 | return;
|
||
784 | } |
||
785 | |||
786 | int magic = textArea.getMagicCaretPosition();
|
||
787 | if(magic == -1) |
||
788 | { |
||
789 | magic = textArea.offsetToX(line, |
||
790 | caret - textArea.getLineStartOffset(line)); |
||
791 | } |
||
792 | |||
793 | caret = textArea.getLineStartOffset(line + 1)
|
||
794 | + textArea.xToOffset(line + 1,magic);
|
||
795 | if(select)
|
||
796 | textArea.select(textArea.getMarkPosition(),caret); |
||
797 | else
|
||
798 | textArea.setCaretPosition(caret); |
||
799 | textArea.setMagicCaretPosition(magic); |
||
800 | } |
||
801 | } |
||
802 | |||
803 | public static class next_page implements ActionListener |
||
804 | { |
||
805 | private boolean select; |
||
806 | |||
807 | public next_page(boolean select) |
||
808 | { |
||
809 | this.select = select;
|
||
810 | } |
||
811 | |||
812 | public void actionPerformed(ActionEvent evt) |
||
813 | { |
||
814 | JEditTextArea textArea = getTextArea(evt); |
||
815 | int lineCount = textArea.getLineCount();
|
||
816 | int firstLine = textArea.getFirstLine();
|
||
817 | int visibleLines = textArea.getVisibleLines();
|
||
818 | int line = textArea.getCaretLine();
|
||
819 | |||
820 | firstLine += visibleLines; |
||
821 | |||
822 | if(firstLine + visibleLines >= lineCount - 1) |
||
823 | firstLine = lineCount - visibleLines; |
||
824 | |||
825 | textArea.setFirstLine(firstLine); |
||
826 | |||
827 | int caret = textArea.getLineStartOffset(
|
||
828 | Math.min(textArea.getLineCount() - 1, |
||
829 | line + visibleLines)); |
||
830 | if(select)
|
||
831 | textArea.select(textArea.getMarkPosition(),caret); |
||
832 | else
|
||
833 | textArea.setCaretPosition(caret); |
||
834 | } |
||
835 | } |
||
836 | |||
837 | public static class next_word implements ActionListener |
||
838 | { |
||
839 | private boolean select; |
||
840 | |||
841 | public next_word(boolean select) |
||
842 | { |
||
843 | this.select = select;
|
||
844 | } |
||
845 | |||
846 | public void actionPerformed(ActionEvent evt) |
||
847 | { |
||
848 | JEditTextArea textArea = getTextArea(evt); |
||
849 | int caret = textArea.getCaretPosition();
|
||
850 | int line = textArea.getCaretLine();
|
||
851 | int lineStart = textArea.getLineStartOffset(line);
|
||
852 | caret -= lineStart; |
||
853 | |||
854 | String lineText = textArea.getLineText(textArea
|
||
855 | .getCaretLine()); |
||
856 | |||
857 | if(caret == lineText.length())
|
||
858 | { |
||
859 | if(lineStart + caret == textArea.getDocumentLength())
|
||
860 | { |
||
861 | textArea.getToolkit().beep(); |
||
862 | return;
|
||
863 | } |
||
864 | caret++; |
||
865 | } |
||
866 | else
|
||
867 | { |
||
868 | String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); |
||
869 | caret = TextUtilities.findWordEnd(lineText,caret,noWordSep); |
||
870 | } |
||
871 | |||
872 | if(select)
|
||
873 | textArea.select(textArea.getMarkPosition(), |
||
874 | lineStart + caret); |
||
875 | else
|
||
876 | textArea.setCaretPosition(lineStart + caret); |
||
877 | } |
||
878 | } |
||
879 | |||
880 | public static class overwrite implements ActionListener |
||
881 | { |
||
882 | public void actionPerformed(ActionEvent evt) |
||
883 | { |
||
884 | JEditTextArea textArea = getTextArea(evt); |
||
885 | textArea.setOverwriteEnabled( |
||
886 | !textArea.isOverwriteEnabled()); |
||
887 | } |
||
888 | } |
||
889 | |||
890 | public static class prev_char implements ActionListener |
||
891 | { |
||
892 | private boolean select; |
||
893 | |||
894 | public prev_char(boolean select) |
||
895 | { |
||
896 | this.select = select;
|
||
897 | } |
||
898 | |||
899 | public void actionPerformed(ActionEvent evt) |
||
900 | { |
||
901 | JEditTextArea textArea = getTextArea(evt); |
||
902 | int caret = textArea.getCaretPosition();
|
||
903 | if(caret == 0) |
||
904 | { |
||
905 | textArea.getToolkit().beep(); |
||
906 | return;
|
||
907 | } |
||
908 | |||
909 | if(select)
|
||
910 | textArea.select(textArea.getMarkPosition(), |
||
911 | caret - 1);
|
||
912 | else
|
||
913 | textArea.setCaretPosition(caret - 1);
|
||
914 | } |
||
915 | } |
||
916 | |||
917 | public static class prev_line implements ActionListener |
||
918 | { |
||
919 | private boolean select; |
||
920 | |||
921 | public prev_line(boolean select) |
||
922 | { |
||
923 | this.select = select;
|
||
924 | } |
||
925 | |||
926 | public void actionPerformed(ActionEvent evt) |
||
927 | { |
||
928 | JEditTextArea textArea = getTextArea(evt); |
||
929 | int caret = textArea.getCaretPosition();
|
||
930 | int line = textArea.getCaretLine();
|
||
931 | |||
932 | if(line == 0) |
||
933 | { |
||
934 | textArea.getToolkit().beep(); |
||
935 | return;
|
||
936 | } |
||
937 | |||
938 | int magic = textArea.getMagicCaretPosition();
|
||
939 | if(magic == -1) |
||
940 | { |
||
941 | magic = textArea.offsetToX(line, |
||
942 | caret - textArea.getLineStartOffset(line)); |
||
943 | } |
||
944 | |||
945 | caret = textArea.getLineStartOffset(line - 1)
|
||
946 | + textArea.xToOffset(line - 1,magic);
|
||
947 | if(select)
|
||
948 | textArea.select(textArea.getMarkPosition(),caret); |
||
949 | else
|
||
950 | textArea.setCaretPosition(caret); |
||
951 | textArea.setMagicCaretPosition(magic); |
||
952 | } |
||
953 | } |
||
954 | |||
955 | public static class prev_page implements ActionListener |
||
956 | { |
||
957 | private boolean select; |
||
958 | |||
959 | public prev_page(boolean select) |
||
960 | { |
||
961 | this.select = select;
|
||
962 | } |
||
963 | |||
964 | public void actionPerformed(ActionEvent evt) |
||
965 | { |
||
966 | JEditTextArea textArea = getTextArea(evt); |
||
967 | int firstLine = textArea.getFirstLine();
|
||
968 | int visibleLines = textArea.getVisibleLines();
|
||
969 | int line = textArea.getCaretLine();
|
||
970 | |||
971 | if(firstLine < visibleLines)
|
||
972 | firstLine = visibleLines; |
||
973 | |||
974 | textArea.setFirstLine(firstLine - visibleLines); |
||
975 | |||
976 | int caret = textArea.getLineStartOffset(
|
||
977 | Math.max(0,line - visibleLines)); |
||
978 | if(select)
|
||
979 | textArea.select(textArea.getMarkPosition(),caret); |
||
980 | else
|
||
981 | textArea.setCaretPosition(caret); |
||
982 | } |
||
983 | } |
||
984 | |||
985 | public static class prev_word implements ActionListener |
||
986 | { |
||
987 | private boolean select; |
||
988 | |||
989 | public prev_word(boolean select) |
||
990 | { |
||
991 | this.select = select;
|
||
992 | } |
||
993 | |||
994 | public void actionPerformed(ActionEvent evt) |
||
995 | { |
||
996 | JEditTextArea textArea = getTextArea(evt); |
||
997 | int caret = textArea.getCaretPosition();
|
||
998 | int line = textArea.getCaretLine();
|
||
999 | int lineStart = textArea.getLineStartOffset(line);
|
||
1000 | caret -= lineStart; |
||
1001 | |||
1002 | String lineText = textArea.getLineText(textArea
|
||
1003 | .getCaretLine()); |
||
1004 | |||
1005 | if(caret == 0) |
||
1006 | { |
||
1007 | if(lineStart == 0) |
||
1008 | { |
||
1009 | textArea.getToolkit().beep(); |
||
1010 | return;
|
||
1011 | } |
||
1012 | caret--; |
||
1013 | } |
||
1014 | else
|
||
1015 | { |
||
1016 | String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); |
||
1017 | caret = TextUtilities.findWordStart(lineText,caret,noWordSep); |
||
1018 | } |
||
1019 | |||
1020 | if(select)
|
||
1021 | textArea.select(textArea.getMarkPosition(), |
||
1022 | lineStart + caret); |
||
1023 | else
|
||
1024 | textArea.setCaretPosition(lineStart + caret); |
||
1025 | } |
||
1026 | } |
||
1027 | |||
1028 | public static class repeat implements ActionListener, |
||
1029 | InputHandler.NonRecordable |
||
1030 | { |
||
1031 | public void actionPerformed(ActionEvent evt) |
||
1032 | { |
||
1033 | JEditTextArea textArea = getTextArea(evt); |
||
1034 | textArea.getInputHandler().setRepeatEnabled(true);
|
||
1035 | String actionCommand = evt.getActionCommand();
|
||
1036 | if(actionCommand != null) |
||
1037 | { |
||
1038 | textArea.getInputHandler().setRepeatCount( |
||
1039 | Integer.parseInt(actionCommand));
|
||
1040 | } |
||
1041 | } |
||
1042 | } |
||
1043 | |||
1044 | public static class toggle_rect implements ActionListener |
||
1045 | { |
||
1046 | public void actionPerformed(ActionEvent evt) |
||
1047 | { |
||
1048 | JEditTextArea textArea = getTextArea(evt); |
||
1049 | textArea.setSelectionRectangular( |
||
1050 | !textArea.isSelectionRectangular()); |
||
1051 | } |
||
1052 | } |
||
1053 | |||
1054 | public static class insert_char implements ActionListener, |
||
1055 | InputHandler.NonRepeatable |
||
1056 | { |
||
1057 | public void actionPerformed(ActionEvent evt) |
||
1058 | { |
||
1059 | JEditTextArea textArea = getTextArea(evt); |
||
1060 | String str = evt.getActionCommand();
|
||
1061 | int repeatCount = textArea.getInputHandler().getRepeatCount();
|
||
1062 | |||
1063 | if(textArea.isEditable())
|
||
1064 | { |
||
1065 | StringBuffer buf = new StringBuffer(); |
||
1066 | for(int i = 0; i < repeatCount; i++) |
||
1067 | buf.append(str); |
||
1068 | textArea.overwriteSetSelectedText(buf.toString()); |
||
1069 | } |
||
1070 | else
|
||
1071 | { |
||
1072 | textArea.getToolkit().beep(); |
||
1073 | } |
||
1074 | } |
||
1075 | } |
||
1076 | } |