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