1
2
3
4
5
6
7
8
9 package com.ochafik.swing.syntaxcoloring;
10 import java.awt.Component;
11 import java.awt.event.ActionEvent;
12 import java.awt.event.ActionListener;
13 import java.awt.event.KeyAdapter;
14 import java.awt.event.KeyEvent;
15 import java.io.BufferedReader;
16 import java.io.IOException;
17 import java.io.StringReader;
18 import java.util.Enumeration;
19 import java.util.EventObject;
20 import java.util.Hashtable;
21
22 import javax.swing.JPopupMenu;
23 import javax.swing.KeyStroke;
24 import javax.swing.text.BadLocationException;
25
26
27
28
29
30
31
32
33
34
35
36
37
38 public abstract class InputHandler extends KeyAdapter
39 {
40
41
42
43
44
45
46
47 public static final String SMART_HOME_END_PROPERTY = "InputHandler.homeEnd";
48 public static final ActionListener COPY=new TAction() { protected void doIt(JEditTextArea ta) {
49 ta.copy();
50 }},
51 CUT=new TAction() { protected void doIt(JEditTextArea ta) {
52 ta.cut();
53 }},
54 PASTE=new TAction() { protected void doIt(JEditTextArea ta) {
55 ta.paste();
56 }}
57
58
59
60
61
62
63 ,
64 SELECT_ALL=new TAction() { protected void doIt(JEditTextArea ta) {
65 ta.selectAll();
66 }};
67
68 public static final ActionListener INSERT_TAB=new TAction() { protected void doIt(JEditTextArea textArea) {
69 if(!textArea.isEditable()) {
70 textArea.getToolkit().beep();
71 return;
72 }
73 int[] start=new int[]{textArea.getSelectionStart()}, end=new int[]{textArea.getSelectionEnd()};
74 if (start[0]!=end[0]) {
75 textArea.setText(increaseIndentation(textArea.getText(),start,end));
76 textArea.setSelectionStart(start[0]);
77 textArea.setSelectionEnd(end[0]);
78 } else textArea.overwriteSetSelectedText("\t");
79 }};
80 public static final ActionListener REMOVE_TAB=new TAction() { protected void doIt(JEditTextArea textArea) {
81 if(!textArea.isEditable()) {
82 textArea.getToolkit().beep();
83 return;
84 }
85 int[] start=new int[]{textArea.getSelectionStart()}, end=new int[]{textArea.getSelectionEnd()};
86 textArea.setText(decreaseIndentation(textArea.getText(),start,end));
87 textArea.setSelectionStart(start[0]);
88 textArea.setSelectionEnd(end[0]);
89 }};
90
91 public static final ActionListener BACKSPACE = new backspace();
92 public static final ActionListener BACKSPACE_WORD = new backspace_word();
93 public static final ActionListener DELETE = new delete();
94 public static final ActionListener DELETE_WORD = new delete_word();
95 public static final ActionListener END = new end(false);
96 public static final ActionListener DOCUMENT_END = new document_end(false);
97 public static final ActionListener SELECT_END = new end(true);
98 public static final ActionListener SELECT_DOC_END = new document_end(true);
99 public static final ActionListener INSERT_BREAK = new insert_break();
100
101 public static final ActionListener HOME = new home(false);
102 public static final ActionListener DOCUMENT_HOME = new document_home(false);
103 public static final ActionListener SELECT_HOME = new home(true);
104 public static final ActionListener SELECT_DOC_HOME = new document_home(true);
105 public static final ActionListener NEXT_CHAR = new next_char(false);
106 public static final ActionListener NEXT_LINE = new next_line(false);
107 public static final ActionListener NEXT_PAGE = new next_page(false);
108 public static final ActionListener NEXT_WORD = new next_word(false);
109 public static final ActionListener SELECT_NEXT_CHAR = new next_char(true);
110 public static final ActionListener SELECT_NEXT_LINE = new next_line(true);
111 public static final ActionListener SELECT_NEXT_PAGE = new next_page(true);
112 public static final ActionListener SELECT_NEXT_WORD = new next_word(true);
113 public static final ActionListener OVERWRITE = new overwrite();
114 public static final ActionListener PREV_CHAR = new prev_char(false);
115 public static final ActionListener PREV_LINE = new prev_line(false);
116 public static final ActionListener PREV_PAGE = new prev_page(false);
117 public static final ActionListener PREV_WORD = new prev_word(false);
118 public static final ActionListener SELECT_PREV_CHAR = new prev_char(true);
119 public static final ActionListener SELECT_PREV_LINE = new prev_line(true);
120 public static final ActionListener SELECT_PREV_PAGE = new prev_page(true);
121 public static final ActionListener SELECT_PREV_WORD = new prev_word(true);
122 public static final ActionListener REPEAT = new repeat();
123 public static final ActionListener TOGGLE_RECT = new toggle_rect();
124
125
126 public static final ActionListener INSERT_CHAR = new insert_char();
127
128 private static Hashtable actions;
129
130 static
131 {
132 actions = new Hashtable();
133 actions.put("copy",COPY);
134 actions.put("cut",CUT);
135 actions.put("paste",PASTE);
136 actions.put("select-all",SELECT_ALL);
137
138
139 actions.put("backspace",BACKSPACE);
140 actions.put("backspace-word",BACKSPACE_WORD);
141 actions.put("delete",DELETE);
142 actions.put("delete-word",DELETE_WORD);
143 actions.put("end",END);
144 actions.put("select-end",SELECT_END);
145 actions.put("document-end",DOCUMENT_END);
146 actions.put("select-doc-end",SELECT_DOC_END);
147 actions.put("insert-break",INSERT_BREAK);
148 actions.put("insert-tab",INSERT_TAB);
149 actions.put("remove-tab",REMOVE_TAB);
150 actions.put("home",HOME);
151 actions.put("select-home",SELECT_HOME);
152 actions.put("document-home",DOCUMENT_HOME);
153 actions.put("select-doc-home",SELECT_DOC_HOME);
154 actions.put("next-char",NEXT_CHAR);
155 actions.put("next-line",NEXT_LINE);
156 actions.put("next-page",NEXT_PAGE);
157 actions.put("next-word",NEXT_WORD);
158 actions.put("select-next-char",SELECT_NEXT_CHAR);
159 actions.put("select-next-line",SELECT_NEXT_LINE);
160 actions.put("select-next-page",SELECT_NEXT_PAGE);
161 actions.put("select-next-word",SELECT_NEXT_WORD);
162 actions.put("overwrite",OVERWRITE);
163 actions.put("prev-char",PREV_CHAR);
164 actions.put("prev-line",PREV_LINE);
165 actions.put("prev-page",PREV_PAGE);
166 actions.put("prev-word",PREV_WORD);
167 actions.put("select-prev-char",SELECT_PREV_CHAR);
168 actions.put("select-prev-line",SELECT_PREV_LINE);
169 actions.put("select-prev-page",SELECT_PREV_PAGE);
170 actions.put("select-prev-word",SELECT_PREV_WORD);
171 actions.put("repeat",REPEAT);
172 actions.put("toggle-rect",TOGGLE_RECT);
173 actions.put("insert-char",INSERT_CHAR);
174 }
175
176
177
178
179
180 public static ActionListener getAction(String name)
181 {
182 return (ActionListener)actions.get(name);
183 }
184
185
186
187
188
189 public static String getActionName(ActionListener listener)
190 {
191 Enumeration enu = getActions();
192 while(enu.hasMoreElements())
193 {
194 String name = (String)enu.nextElement();
195 ActionListener _listener = getAction(name);
196 if(_listener == listener)
197 return name;
198 }
199 return null;
200 }
201
202
203
204
205 public static Enumeration getActions()
206 {
207 return actions.keys();
208 }
209
210
211
212
213
214
215
216 public abstract void addDefaultKeyBindings();
217
218
219
220
221
222
223
224 public abstract void addKeyBinding(String keyBinding, ActionListener action);
225 public abstract void addKeyBinding(KeyStroke keyStroke, ActionListener action);
226
227
228
229
230 public abstract void removeKeyBinding(String keyBinding);
231
232
233
234
235 public abstract void removeAllKeyBindings();
236
237
238
239
240
241
242 public void grabNextKeyStroke(ActionListener listener)
243 {
244 grabAction = listener;
245 }
246
247
248
249
250
251
252 public boolean isRepeatEnabled()
253 {
254 return repeat;
255 }
256
257
258
259
260
261
262 public void setRepeatEnabled(boolean repeat)
263 {
264 this.repeat = repeat;
265 }
266
267
268
269
270 public int getRepeatCount()
271 {
272 return (repeat ? Math.max(1,repeatCount) : 1);
273 }
274
275
276
277
278
279 public void setRepeatCount(int repeatCount)
280 {
281 this.repeatCount = repeatCount;
282 }
283
284
285
286
287
288 public InputHandler.MacroRecorder getMacroRecorder()
289 {
290 return recorder;
291 }
292
293
294
295
296
297
298 public void setMacroRecorder(InputHandler.MacroRecorder recorder)
299 {
300 this.recorder = recorder;
301 }
302
303
304
305
306
307
308 public abstract InputHandler copy();
309
310
311
312
313
314
315
316
317 public void executeAction(ActionListener listener, Object source,
318 String actionCommand)
319 {
320
321 ActionEvent evt = new ActionEvent(source,
322 ActionEvent.ACTION_PERFORMED,
323 actionCommand);
324
325
326
327 if(listener instanceof Wrapper)
328 {
329 listener.actionPerformed(evt);
330 return;
331 }
332
333
334 boolean _repeat = repeat;
335 int _repeatCount = getRepeatCount();
336
337
338 if(listener instanceof InputHandler.NonRepeatable)
339 listener.actionPerformed(evt);
340 else
341 {
342 for(int i = 0; i < Math.max(1,repeatCount); i++)
343 listener.actionPerformed(evt);
344 }
345
346
347
348 if(grabAction == null)
349 {
350 if(recorder != null)
351 {
352 if(!(listener instanceof InputHandler.NonRecordable))
353 {
354 if(_repeatCount != 1)
355 recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount));
356
357 recorder.actionPerformed(listener,actionCommand);
358 }
359 }
360
361
362
363 if(_repeat)
364 {
365 repeat = false;
366 repeatCount = 0;
367 }
368 }
369 }
370
371
372
373
374
375 public static JEditTextArea getTextArea(EventObject evt)
376 {
377 if(evt != null)
378 {
379 Object o = evt.getSource();
380 if(o instanceof Component)
381 {
382
383 Component c = (Component)o;
384 for(;;)
385 {
386 if(c instanceof JEditTextArea)
387 return (JEditTextArea)c;
388 else if(c == null)
389 break;
390 if(c instanceof JPopupMenu)
391 c = ((JPopupMenu)c)
392 .getInvoker();
393 else
394 c = c.getParent();
395 }
396 }
397 }
398
399
400 System.err.println("BUG: getTextArea() returning null");
401 System.err.println("Report this to Slava Pestov <sp@gjt.org>");
402 return null;
403 }
404
405
406
407
408
409
410
411
412 protected void handleGrabAction(KeyEvent evt)
413 {
414
415
416 ActionListener _grabAction = grabAction;
417 grabAction = null;
418 executeAction(_grabAction,evt.getSource(),
419 String.valueOf(evt.getKeyChar()));
420 }
421
422
423 protected ActionListener grabAction;
424 protected boolean repeat;
425 protected int repeatCount;
426 protected InputHandler.MacroRecorder recorder;
427
428
429
430
431
432 public interface NonRepeatable {}
433
434
435
436
437
438 public interface NonRecordable {}
439
440
441
442
443
444 public interface Wrapper {}
445
446
447
448
449 public interface MacroRecorder
450 {
451 void actionPerformed(ActionListener listener,
452 String actionCommand);
453 }
454 static abstract class TAction implements ActionListener {
455 public void actionPerformed(ActionEvent evt) {
456 JEditTextArea textArea = getTextArea(evt);
457 doIt(textArea);
458 }
459 protected abstract void doIt(JEditTextArea ta);
460 }
461 public static class backspace implements ActionListener
462 {
463 public void actionPerformed(ActionEvent evt)
464 {
465 JEditTextArea textArea = getTextArea(evt);
466
467 if(!textArea.isEditable())
468 {
469 textArea.getToolkit().beep();
470 return;
471 }
472
473 if(textArea.getSelectionStart()
474 != textArea.getSelectionEnd())
475 {
476 textArea.setSelectedText("");
477 }
478 else
479 {
480 int caret = textArea.getCaretPosition();
481 if(caret == 0)
482 {
483 textArea.getToolkit().beep();
484 return;
485 }
486 try
487 {
488 textArea.getDocument().remove(caret - 1,1);
489 }
490 catch(BadLocationException bl)
491 {
492 bl.printStackTrace();
493 }
494 }
495 }
496 }
497
498 public static class backspace_word implements ActionListener
499 {
500 public void actionPerformed(ActionEvent evt)
501 {
502 JEditTextArea textArea = getTextArea(evt);
503 int start = textArea.getSelectionStart();
504 if(start != textArea.getSelectionEnd())
505 {
506 textArea.setSelectedText("");
507 }
508
509 int line = textArea.getCaretLine();
510 int lineStart = textArea.getLineStartOffset(line);
511 int caret = start - lineStart;
512
513 String lineText = textArea.getLineText(textArea
514 .getCaretLine());
515
516 if(caret == 0)
517 {
518 if(lineStart == 0)
519 {
520 textArea.getToolkit().beep();
521 return;
522 }
523 caret--;
524 }
525 else
526 {
527 String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
528 caret = TextUtilities.findWordStart(lineText,caret,noWordSep);
529 }
530
531 try
532 {
533 textArea.getDocument().remove(
534 caret + lineStart,
535 start - (caret + lineStart));
536 }
537 catch(BadLocationException bl)
538 {
539 bl.printStackTrace();
540 }
541 }
542 }
543
544 public static class delete implements ActionListener
545 {
546 public void actionPerformed(ActionEvent evt)
547 {
548 JEditTextArea textArea = getTextArea(evt);
549
550 if(!textArea.isEditable())
551 {
552 textArea.getToolkit().beep();
553 return;
554 }
555
556 if(textArea.getSelectionStart()
557 != textArea.getSelectionEnd())
558 {
559 textArea.setSelectedText("");
560 }
561 else
562 {
563 int caret = textArea.getCaretPosition();
564 if(caret == textArea.getDocumentLength())
565 {
566 textArea.getToolkit().beep();
567 return;
568 }
569 try
570 {
571 textArea.getDocument().remove(caret,1);
572 }
573 catch(BadLocationException bl)
574 {
575 bl.printStackTrace();
576 }
577 }
578 }
579 }
580
581 public static class delete_word implements ActionListener
582 {
583 public void actionPerformed(ActionEvent evt)
584 {
585 JEditTextArea textArea = getTextArea(evt);
586 int start = textArea.getSelectionStart();
587 if(start != textArea.getSelectionEnd())
588 {
589 textArea.setSelectedText("");
590 }
591
592 int line = textArea.getCaretLine();
593 int lineStart = textArea.getLineStartOffset(line);
594 int caret = start - lineStart;
595
596 String lineText = textArea.getLineText(textArea
597 .getCaretLine());
598
599 if(caret == lineText.length())
600 {
601 if(lineStart + caret == textArea.getDocumentLength())
602 {
603 textArea.getToolkit().beep();
604 return;
605 }
606 caret++;
607 }
608 else
609 {
610 String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
611 caret = TextUtilities.findWordEnd(lineText,caret,noWordSep);
612 }
613
614 try
615 {
616 textArea.getDocument().remove(start,
617 (caret + lineStart) - start);
618 }
619 catch(BadLocationException bl)
620 {
621 bl.printStackTrace();
622 }
623 }
624 }
625
626 public static class end implements ActionListener
627 {
628 private boolean select;
629
630 public end(boolean select)
631 {
632 this.select = select;
633 }
634
635 public void actionPerformed(ActionEvent evt)
636 {
637 JEditTextArea textArea = getTextArea(evt);
638
639 int caret = textArea.getCaretPosition();
640
641 int lastOfLine = textArea.getLineEndOffset(
642 textArea.getCaretLine()) - 1;
643 int lastVisibleLine = textArea.getFirstLine()
644 + textArea.getVisibleLines();
645 if(lastVisibleLine >= textArea.getLineCount())
646 {
647 lastVisibleLine = Math.min(textArea.getLineCount() - 1,
648 lastVisibleLine);
649 }
650 else
651 lastVisibleLine -= (textArea.getElectricScroll() + 1);
652
653 int lastVisible = textArea.getLineEndOffset(lastVisibleLine) - 1;
654 int lastDocument = textArea.getDocumentLength();
655
656 if(caret == lastDocument)
657 {
658 textArea.getToolkit().beep();
659 return;
660 }
661 else if(!Boolean.TRUE.equals(textArea.getClientProperty(
662 SMART_HOME_END_PROPERTY)))
663 caret = lastOfLine;
664 else if(caret == lastVisible)
665 caret = lastDocument;
666 else if(caret == lastOfLine)
667 caret = lastVisible;
668 else
669 caret = lastOfLine;
670
671 if(select)
672 textArea.select(textArea.getMarkPosition(),caret);
673 else
674 textArea.setCaretPosition(caret);
675 }
676 }
677
678 public static class document_end implements ActionListener
679 {
680 private boolean select;
681
682 public document_end(boolean select)
683 {
684 this.select = select;
685 }
686
687 public void actionPerformed(ActionEvent evt)
688 {
689 JEditTextArea textArea = getTextArea(evt);
690 if(select)
691 textArea.select(textArea.getMarkPosition(),
692 textArea.getDocumentLength());
693 else
694 textArea.setCaretPosition(textArea
695 .getDocumentLength());
696 }
697 }
698
699 public static class home implements ActionListener
700 {
701 private boolean select;
702
703 public home(boolean select)
704 {
705 this.select = select;
706 }
707
708 public void actionPerformed(ActionEvent evt)
709 {
710 JEditTextArea textArea = getTextArea(evt);
711
712 int caret = textArea.getCaretPosition();
713
714 int firstLine = textArea.getFirstLine();
715
716 int firstOfLine = textArea.getLineStartOffset(
717 textArea.getCaretLine());
718 int firstVisibleLine = (firstLine == 0 ? 0 :
719 firstLine + textArea.getElectricScroll());
720 int firstVisible = textArea.getLineStartOffset(
721 firstVisibleLine);
722
723 if(caret == 0)
724 {
725 textArea.getToolkit().beep();
726 return;
727 }
728 else if(!Boolean.TRUE.equals(textArea.getClientProperty(
729 SMART_HOME_END_PROPERTY)))
730 caret = firstOfLine;
731 else if(caret == firstVisible)
732 caret = 0;
733 else if(caret == firstOfLine)
734 caret = firstVisible;
735 else
736 caret = firstOfLine;
737
738 if(select)
739 textArea.select(textArea.getMarkPosition(),caret);
740 else
741 textArea.setCaretPosition(caret);
742 }
743 }
744
745 public static class document_home implements ActionListener
746 {
747 private boolean select;
748
749 public document_home(boolean select)
750 {
751 this.select = select;
752 }
753
754 public void actionPerformed(ActionEvent evt)
755 {
756 JEditTextArea textArea = getTextArea(evt);
757 if(select)
758 textArea.select(textArea.getMarkPosition(),0);
759 else
760 textArea.setCaretPosition(0);
761 }
762 }
763
764 public static class insert_break implements ActionListener
765 {
766 public void actionPerformed(ActionEvent evt)
767 {
768 JEditTextArea textArea = getTextArea(evt);
769
770 if(!textArea.isEditable())
771 {
772 textArea.getToolkit().beep();
773 return;
774 }
775
776 textArea.setSelectedText("\n");
777 }
778 }
779
780 public static String increaseIndentation(String text, int selectionStart[], int selectionEnd[]) {
781 int start=selectionStart[0];
782 int end=selectionEnd[0];
783 start=text.lastIndexOf("\n",text.charAt(start)=='\n'&&!(start==0||text.charAt(start-1)=='\n') ? start-1 : start);
784
785 if (start<0) start=0; else start=start+1;
786 end=text.indexOf("\n",end);
787 boolean endsWithLine=end>=0;
788 if (end<0) end=text.length(); else end++;
789 String middle=text.substring(start,end);
790 StringBuffer buf=new StringBuffer(text.substring(0,start));
791 try {
792 BufferedReader in=new BufferedReader(new StringReader(middle));
793 String line;
794 int lines=0;
795 boolean firstLine=true;
796 while ((line=in.readLine())!=null) {
797 lines++;
798 if (!firstLine) buf.append('\n');
799 buf.append('\t');
800 buf.append(line);
801 firstLine=false;
802 }
803 if (endsWithLine) buf.append('\n');
804 buf.append(text.substring(end));
805 selectionStart[0]++;
806 selectionEnd[0]+=lines;
807 return buf.toString();
808 } catch (IOException ex) {
809 ex.printStackTrace();
810 return null;
811 }
812 }
813 public static String decreaseIndentation(String text, int selectionStart[], int selectionEnd[]) {
814 int start=selectionStart[0];
815 int end=selectionEnd[0];
816
817 start=text.lastIndexOf("\n",text.charAt(start)=='\n'&&!(start==0||text.charAt(start-1)=='\n') ? start-1 : start);
818 if (start<0) start=0; else start=start+1;
819 end=text.indexOf("\n",end);
820 boolean endsWithLine=end>=0;
821 if (end<0) end=text.length(); else end++;
822 String middle=text.substring(start,end);
823 StringBuffer buf=new StringBuffer(text.substring(0,start));
824 try {
825 BufferedReader in=new BufferedReader(new StringReader(middle));
826 String line;
827 int lines=0;
828 boolean firstLine=true;
829 boolean firstLineDecreased=false;
830 while ((line=in.readLine())!=null) {
831 if (!firstLine) buf.append('\n');
832 if (!line.equals("")) {
833 char c=line.charAt(0);
834 if (c==' '||c=='\t') {
835 if (firstLine) firstLineDecreased=true;
836 line=line.substring(1);
837 lines++;
838 }
839 buf.append(line);
840 }
841 firstLine=false;
842 }
843 if (endsWithLine) buf.append('\n');
844 buf.append(text.substring(end));
845 if (firstLineDecreased) selectionStart[0]--;
846 selectionEnd[0]-=lines;
847 return buf.toString();
848 } catch (IOException ex) {
849 ex.printStackTrace();
850 return null;
851 }
852 }
853 public static class next_char implements ActionListener
854 {
855 private boolean select;
856
857 public next_char(boolean select)
858 {
859 this.select = select;
860 }
861
862 public void actionPerformed(ActionEvent evt)
863 {
864 JEditTextArea textArea = getTextArea(evt);
865 int caret = textArea.getCaretPosition();
866 if(caret == textArea.getDocumentLength())
867 {
868 textArea.getToolkit().beep();
869 return;
870 }
871
872 if(select)
873 textArea.select(textArea.getMarkPosition(),
874 caret + 1);
875 else
876 textArea.setCaretPosition(caret + 1);
877 }
878 }
879
880 public static class next_line implements ActionListener
881 {
882 private boolean select;
883
884 public next_line(boolean select)
885 {
886 this.select = select;
887 }
888
889 public void actionPerformed(ActionEvent evt)
890 {
891 JEditTextArea textArea = getTextArea(evt);
892 int caret = textArea.getCaretPosition();
893 int line = textArea.getCaretLine();
894
895 if(line == textArea.getLineCount() - 1)
896 {
897 textArea.getToolkit().beep();
898 return;
899 }
900
901 int magic = textArea.getMagicCaretPosition();
902 if(magic == -1)
903 {
904 magic = textArea.offsetToX(line,
905 caret - textArea.getLineStartOffset(line));
906 }
907
908 caret = textArea.getLineStartOffset(line + 1)
909 + textArea.xToOffset(line + 1,magic);
910 if(select)
911 textArea.select(textArea.getMarkPosition(),caret);
912 else
913 textArea.setCaretPosition(caret);
914 textArea.setMagicCaretPosition(magic);
915 }
916 }
917
918 public static class next_page implements ActionListener
919 {
920 private boolean select;
921
922 public next_page(boolean select)
923 {
924 this.select = select;
925 }
926
927 public void actionPerformed(ActionEvent evt)
928 {
929 JEditTextArea textArea = getTextArea(evt);
930 int lineCount = textArea.getLineCount();
931 int firstLine = textArea.getFirstLine();
932 int visibleLines = textArea.getVisibleLines();
933 int line = textArea.getCaretLine();
934
935 firstLine += visibleLines;
936
937 if(firstLine + visibleLines >= lineCount - 1)
938 firstLine = lineCount - visibleLines;
939
940 textArea.setFirstLine(firstLine);
941
942 int caret = textArea.getLineStartOffset(
943 Math.min(textArea.getLineCount() - 1,
944 line + visibleLines));
945 if(select)
946 textArea.select(textArea.getMarkPosition(),caret);
947 else
948 textArea.setCaretPosition(caret);
949 }
950 }
951
952 public static class next_word implements ActionListener
953 {
954 private boolean select;
955
956 public next_word(boolean select)
957 {
958 this.select = select;
959 }
960
961 public void actionPerformed(ActionEvent evt)
962 {
963 JEditTextArea textArea = getTextArea(evt);
964 int caret = textArea.getCaretPosition();
965 int line = textArea.getCaretLine();
966 int lineStart = textArea.getLineStartOffset(line);
967 caret -= lineStart;
968
969 String lineText = textArea.getLineText(textArea
970 .getCaretLine());
971
972 if(caret == lineText.length())
973 {
974 if(lineStart + caret == textArea.getDocumentLength())
975 {
976 textArea.getToolkit().beep();
977 return;
978 }
979 caret++;
980 }
981 else
982 {
983 String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
984 caret = TextUtilities.findWordEnd(lineText,caret,noWordSep);
985 }
986
987 if(select)
988 textArea.select(textArea.getMarkPosition(),
989 lineStart + caret);
990 else
991 textArea.setCaretPosition(lineStart + caret);
992 }
993 }
994
995 public static class overwrite implements ActionListener
996 {
997 public void actionPerformed(ActionEvent evt)
998 {
999 JEditTextArea textArea = getTextArea(evt);
1000 textArea.setOverwriteEnabled(
1001 !textArea.isOverwriteEnabled());
1002 }
1003 }
1004
1005 public static class prev_char implements ActionListener
1006 {
1007 private boolean select;
1008
1009 public prev_char(boolean select)
1010 {
1011 this.select = select;
1012 }
1013
1014 public void actionPerformed(ActionEvent evt)
1015 {
1016 JEditTextArea textArea = getTextArea(evt);
1017 int caret = textArea.getCaretPosition();
1018 if(caret == 0)
1019 {
1020 textArea.getToolkit().beep();
1021 return;
1022 }
1023
1024 if(select)
1025 textArea.select(textArea.getMarkPosition(),
1026 caret - 1);
1027 else
1028 textArea.setCaretPosition(caret - 1);
1029 }
1030 }
1031
1032 public static class prev_line implements ActionListener
1033 {
1034 private boolean select;
1035
1036 public prev_line(boolean select)
1037 {
1038 this.select = select;
1039 }
1040
1041 public void actionPerformed(ActionEvent evt)
1042 {
1043 JEditTextArea textArea = getTextArea(evt);
1044 int caret = textArea.getCaretPosition();
1045 int line = textArea.getCaretLine();
1046
1047 if(line == 0)
1048 {
1049 textArea.getToolkit().beep();
1050 return;
1051 }
1052
1053 int magic = textArea.getMagicCaretPosition();
1054 if(magic == -1)
1055 {
1056 magic = textArea.offsetToX(line,
1057 caret - textArea.getLineStartOffset(line));
1058 }
1059
1060 caret = textArea.getLineStartOffset(line - 1)
1061 + textArea.xToOffset(line - 1,magic);
1062 if(select)
1063 textArea.select(textArea.getMarkPosition(),caret);
1064 else
1065 textArea.setCaretPosition(caret);
1066 textArea.setMagicCaretPosition(magic);
1067 }
1068 }
1069
1070 public static class prev_page implements ActionListener
1071 {
1072 private boolean select;
1073
1074 public prev_page(boolean select)
1075 {
1076 this.select = select;
1077 }
1078
1079 public void actionPerformed(ActionEvent evt)
1080 {
1081 JEditTextArea textArea = getTextArea(evt);
1082 int firstLine = textArea.getFirstLine();
1083 int visibleLines = textArea.getVisibleLines();
1084 int line = textArea.getCaretLine();
1085
1086 if(firstLine < visibleLines)
1087 firstLine = visibleLines;
1088
1089 textArea.setFirstLine(firstLine - visibleLines);
1090
1091 int caret = textArea.getLineStartOffset(
1092 Math.max(0,line - visibleLines));
1093 if(select)
1094 textArea.select(textArea.getMarkPosition(),caret);
1095 else
1096 textArea.setCaretPosition(caret);
1097 }
1098 }
1099
1100 public static class prev_word implements ActionListener
1101 {
1102 private boolean select;
1103
1104 public prev_word(boolean select)
1105 {
1106 this.select = select;
1107 }
1108
1109 public void actionPerformed(ActionEvent evt)
1110 {
1111 JEditTextArea textArea = getTextArea(evt);
1112 int caret = textArea.getCaretPosition();
1113 int line = textArea.getCaretLine();
1114 int lineStart = textArea.getLineStartOffset(line);
1115 caret -= lineStart;
1116
1117 String lineText = textArea.getLineText(textArea
1118 .getCaretLine());
1119
1120 if(caret == 0)
1121 {
1122 if(lineStart == 0)
1123 {
1124 textArea.getToolkit().beep();
1125 return;
1126 }
1127 caret--;
1128 }
1129 else
1130 {
1131 String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
1132 caret = TextUtilities.findWordStart(lineText,caret,noWordSep);
1133 }
1134
1135 if(select)
1136 textArea.select(textArea.getMarkPosition(),
1137 lineStart + caret);
1138 else
1139 textArea.setCaretPosition(lineStart + caret);
1140 }
1141 }
1142
1143 public static class repeat implements ActionListener,
1144 InputHandler.NonRecordable
1145 {
1146 public void actionPerformed(ActionEvent evt)
1147 {
1148 JEditTextArea textArea = getTextArea(evt);
1149 textArea.getInputHandler().setRepeatEnabled(true);
1150 String actionCommand = evt.getActionCommand();
1151 if(actionCommand != null)
1152 {
1153 textArea.getInputHandler().setRepeatCount(
1154 Integer.parseInt(actionCommand));
1155 }
1156 }
1157 }
1158
1159 public static class toggle_rect implements ActionListener
1160 {
1161 public void actionPerformed(ActionEvent evt)
1162 {
1163 JEditTextArea textArea = getTextArea(evt);
1164 textArea.setSelectionRectangular(
1165 !textArea.isSelectionRectangular());
1166 }
1167 }
1168
1169 public static class insert_char implements ActionListener,
1170 InputHandler.NonRepeatable
1171 {
1172 public void actionPerformed(ActionEvent evt)
1173 {
1174 JEditTextArea textArea = getTextArea(evt);
1175 String str = evt.getActionCommand();
1176 int repeatCount = textArea.getInputHandler().getRepeatCount();
1177
1178 if(textArea.isEditable())
1179 {
1180 StringBuffer buf = new StringBuffer();
1181 for(int i = 0; i < repeatCount; i++)
1182 buf.append(str);
1183 textArea.overwriteSetSelectedText(buf.toString());
1184 }
1185 else
1186 {
1187 textArea.getToolkit().beep();
1188 }
1189 }
1190 }
1191 }