1 /* DefaultEditorKit.java --
2 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.text;
41 import java.awt.Toolkit;
42 import java.awt.event.ActionEvent;
43 import java.io.BufferedReader;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.io.InputStreamReader;
47 import java.io.OutputStream;
48 import java.io.OutputStreamWriter;
49 import java.io.Reader;
50 import java.io.Writer;
52 import javax.swing.Action;
55 * The default implementation of {@link EditorKit}. This <code>EditorKit</code>
56 * a plain text <code>Document</code> and several commands that together
57 * make up a basic editor, like cut / copy + paste.
59 * @author original author unknown
60 * @author Roman Kennke (roman@kennke.org)
62 public class DefaultEditorKit extends EditorKit
65 * Creates a beep on the PC speaker.
69 public static class BeepAction
73 * Creates a new <code>BeepAction</code>.
81 * Performs the <code>Action</code>.
83 * @param event the action event describing the user action
85 public void actionPerformed(ActionEvent event)
87 Toolkit.getDefaultToolkit().beep();
92 * Copies the selected content into the system clipboard.
94 * @see Toolkit#getSystemClipboard()
98 public static class CopyAction
103 * Create a new <code>CopyAction</code>.
111 * Performs the <code>Action</code>.
113 * @param event the action event describing the user action
115 public void actionPerformed(ActionEvent event)
117 // FIXME: Implement me. Tookit.getSystemClipboard should be used
124 * Copies the selected content into the system clipboard and deletes the
127 * @see Toolkit#getSystemClipboard()
131 public static class CutAction
136 * Create a new <code>CutAction</code>.
144 * Performs the <code>Action</code>.
146 * @param event the action event describing the user action
148 public void actionPerformed(ActionEvent event)
150 // FIXME: Implement me. Tookit.getSystemClipboard should be used
156 * Copies content from the system clipboard into the editor.
158 * @see Toolkit#getSystemClipboard()
162 public static class PasteAction
167 * Create a new <code>PasteAction</code>.
175 * Performs the <code>Action</code>.
177 * @param event the action event describing the user action
179 public void actionPerformed(ActionEvent event)
181 // FIXME: Implement me. Tookit.getSystemClipboard should be used
187 * This action is executed as default action when a KEY_TYPED
188 * event is received and no keymap entry exists for that. The purpose
189 * of this action is to filter out a couple of characters. This includes
190 * the control characters and characters with the ALT-modifier.
192 * If an event does not get filtered, it is inserted into the document
193 * of the text component. If there is some text selected in the text
194 * component, this text will be replaced.
196 public static class DefaultKeyTypedAction
201 * Creates a new <code>DefaultKeyTypedAction</code>.
203 public DefaultKeyTypedAction()
205 super(defaultKeyTypedAction);
209 * Performs the <code>Action</code>.
211 * @param event the action event describing the user action
213 public void actionPerformed(ActionEvent event)
215 // first we filter the following events:
216 // - control characters
217 // - key events with the ALT modifier (FIXME: filter that too!)
218 char c = event.getActionCommand().charAt(0);
219 if (Character.isISOControl(c))
222 JTextComponent t = getTextComponent(event);
227 t.getDocument().insertString(t.getCaret().getDot(),
228 event.getActionCommand(), null);
229 t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
230 t.getDocument().getEndPosition()
233 catch (BadLocationException be)
235 // FIXME: we're not authorized to throw this.. swallow it?
242 * This action inserts a newline character into the document
243 * of the text component. This is typically triggered by hitting
244 * ENTER on the keyboard.
246 public static class InsertBreakAction
251 * Creates a new <code>InsertBreakAction</code>.
253 public InsertBreakAction()
255 super(insertBreakAction);
259 * Performs the <code>Action</code>.
261 * @param event the action event describing the user action
263 public void actionPerformed(ActionEvent event)
265 JTextComponent t = getTextComponent(event);
266 t.replaceSelection("\n");
271 * Places content into the associated editor. If there currently is a
272 * selection, this selection is replaced.
274 // FIXME: Figure out what this Action is supposed to do. Obviously text
275 // that is entered by the user is inserted through DefaultKeyTypedAction.
276 public static class InsertContentAction
281 * Creates a new <code>InsertContentAction</code>.
283 public InsertContentAction()
285 super(insertContentAction);
289 * Performs the <code>Action</code>.
291 * @param event the action event describing the user action
293 public void actionPerformed(ActionEvent event)
299 * Inserts a TAB character into the text editor.
301 public static class InsertTabAction
306 * Creates a new <code>TabAction</code>.
308 public InsertTabAction()
310 super(insertTabAction);
314 * Performs the <code>Action</code>.
316 * @param event the action event describing the user action
318 public void actionPerformed(ActionEvent event)
320 // FIXME: Implement this.
325 * The serial version of DefaultEditorKit.
327 private static final long serialVersionUID = 9017245433028523428L;
330 * The name of the <code>Action</code> that moves the caret one character
335 public static final String backwardAction = "caret-backward";
338 * The name of the <code>Action</code> that creates a beep in the speaker.
342 public static final String beepAction = "beep";
345 * The name of the <code>Action</code> that moves the caret to the beginning
346 * of the <code>Document</code>.
350 public static final String beginAction = "caret-begin";
353 * The name of the <code>Action</code> that moves the caret to the beginning
354 * of the current line.
358 public static final String beginLineAction = "caret-begin-line";
361 * The name of the <code>Action</code> that moves the caret to the beginning
362 * of the current paragraph.
366 public static final String beginParagraphAction = "caret-begin-paragraph";
369 * The name of the <code>Action</code> that moves the caret to the beginning
370 * of the current word.
374 public static final String beginWordAction = "caret-begin-word";
377 * The name of the <code>Action</code> that copies the selected content
378 * into the system clipboard.
382 public static final String copyAction = "copy-to-clipboard";
385 * The name of the <code>Action</code> that copies the selected content
386 * into the system clipboard and removes the selection.
390 public static final String cutAction = "cut-to-clipboard";
393 * The name of the <code>Action</code> that is performed by default if
394 * a key is typed and there is no keymap entry.
398 public static final String defaultKeyTypedAction = "default-typed";
401 * The name of the <code>Action</code> that deletes the character that
402 * follows the current caret position.
406 public static final String deleteNextCharAction = "delete-next";
409 * The name of the <code>Action</code> that deletes the character that
410 * precedes the current caret position.
414 public static final String deletePrevCharAction = "delete-previous";
417 * The name of the <code>Action</code> that moves the caret one line down.
421 public static final String downAction = "caret-down";
424 * The name of the <code>Action</code> that moves the caret to the end
425 * of the <code>Document</code>.
429 public static final String endAction = "caret-end";
432 * The name of the <code>Action</code> that moves the caret to the end
433 * of the current line.
437 public static final String endLineAction = "caret-end-line";
440 * When a document is read and an CRLF is encountered, then we add a property
441 * with this name and a value of "\r\n".
443 public static final String EndOfLineStringProperty = "__EndOfLine__";
446 * The name of the <code>Action</code> that moves the caret to the end
447 * of the current paragraph.
451 public static final String endParagraphAction = "caret-end-paragraph";
454 * The name of the <code>Action</code> that moves the caret to the end
455 * of the current word.
459 public static final String endWordAction = "caret-end-word";
462 * The name of the <code>Action</code> that moves the caret one character
467 public static final String forwardAction = "caret-forward";
470 * The name of the <code>Action</code> that inserts a line break.
474 public static final String insertBreakAction = "insert-break";
477 * The name of the <code>Action</code> that inserts some content.
481 public static final String insertContentAction = "insert-content";
484 * The name of the <code>Action</code> that inserts a TAB.
488 public static final String insertTabAction = "insert-tab";
491 * The name of the <code>Action</code> that moves the caret to the beginning
496 public static final String nextWordAction = "caret-next-word";
499 * The name of the <code>Action</code> that moves the caret one page down.
503 public static final String pageDownAction = "page-down";
506 * The name of the <code>Action</code> that moves the caret one page up.
510 public static final String pageUpAction = "page-up";
513 * The name of the <code>Action</code> that copies content from the system
514 * clipboard into the document.
518 public static final String pasteAction = "paste-from-clipboard";
521 * The name of the <code>Action</code> that moves the caret to the beginning
522 * of the previous word.
526 public static final String previousWordAction = "caret-previous-word";
529 * The name of the <code>Action</code> that sets the editor in read only
534 public static final String readOnlyAction = "set-read-only";
537 * The name of the <code>Action</code> that selects the whole document.
541 public static final String selectAllAction = "select-all";
544 * The name of the <code>Action</code> that moves the caret one character
545 * backwards, possibly extending the current selection.
549 public static final String selectionBackwardAction = "selection-backward";
552 * The name of the <code>Action</code> that moves the caret to the beginning
553 * of the document, possibly extending the current selection.
557 public static final String selectionBeginAction = "selection-begin";
560 * The name of the <code>Action</code> that moves the caret to the beginning
561 * of the current line, possibly extending the current selection.
565 public static final String selectionBeginLineAction = "selection-begin-line";
568 * The name of the <code>Action</code> that moves the caret to the beginning
569 * of the current paragraph, possibly extending the current selection.
573 public static final String selectionBeginParagraphAction =
574 "selection-begin-paragraph";
577 * The name of the <code>Action</code> that moves the caret to the beginning
578 * of the current word, possibly extending the current selection.
582 public static final String selectionBeginWordAction = "selection-begin-word";
585 * The name of the <code>Action</code> that moves the caret one line down,
586 * possibly extending the current selection.
590 public static final String selectionDownAction = "selection-down";
593 * The name of the <code>Action</code> that moves the caret to the end
594 * of the document, possibly extending the current selection.
598 public static final String selectionEndAction = "selection-end";
601 * The name of the <code>Action</code> that moves the caret to the end
602 * of the current line, possibly extending the current selection.
606 public static final String selectionEndLineAction = "selection-end-line";
609 * The name of the <code>Action</code> that moves the caret to the end
610 * of the current paragraph, possibly extending the current selection.
614 public static final String selectionEndParagraphAction =
615 "selection-end-paragraph";
618 * The name of the <code>Action</code> that moves the caret to the end
619 * of the current word, possibly extending the current selection.
623 public static final String selectionEndWordAction = "selection-end-word";
626 * The name of the <code>Action</code> that moves the caret one character
627 * forwards, possibly extending the current selection.
631 public static final String selectionForwardAction = "selection-forward";
634 * The name of the <code>Action</code> that moves the caret to the beginning
635 * of the next word, possibly extending the current selection.
639 public static final String selectionNextWordAction = "selection-next-word";
642 * The name of the <code>Action</code> that moves the caret to the beginning
643 * of the previous word, possibly extending the current selection.
647 public static final String selectionPreviousWordAction =
648 "selection-previous-word";
651 * The name of the <code>Action</code> that moves the caret one line up,
652 * possibly extending the current selection.
656 public static final String selectionUpAction = "selection-up";
659 * The name of the <code>Action</code> that selects the line around the
664 public static final String selectLineAction = "select-line";
667 * The name of the <code>Action</code> that selects the paragraph around the
672 public static final String selectParagraphAction = "select-paragraph";
675 * The name of the <code>Action</code> that selects the word around the
680 public static final String selectWordAction = "select-word";
683 * The name of the <code>Action</code> that moves the caret one line up.
687 public static final String upAction = "caret-up";
690 * The name of the <code>Action</code> that sets the editor in read-write
695 public static final String writableAction = "set-writable";
698 * Creates a new <code>DefaultEditorKit</code>.
700 public DefaultEditorKit()
705 * The <code>Action</code>s that are supported by the
706 * <code>DefaultEditorKit</code>.
708 // TODO: All these inner classes look ugly. Maybe work out a better way
710 private static Action[] defaultActions =
715 new DefaultKeyTypedAction(),
716 new InsertBreakAction(),
717 new InsertContentAction(),
718 new InsertTabAction(),
720 new TextAction(deleteNextCharAction)
722 public void actionPerformed(ActionEvent event)
724 JTextComponent t = getTextComponent(event);
729 int pos = t.getCaret().getDot();
730 if (pos < t.getDocument().getEndPosition().getOffset())
732 t.getDocument().remove(t.getCaret().getDot(), 1);
735 catch (BadLocationException e)
737 // FIXME: we're not authorized to throw this.. swallow it?
742 new TextAction(deletePrevCharAction)
744 public void actionPerformed(ActionEvent event)
746 JTextComponent t = getTextComponent(event);
751 int pos = t.getCaret().getDot();
752 if (pos > t.getDocument().getStartPosition().getOffset())
754 t.getDocument().remove(pos - 1, 1);
755 t.getCaret().setDot(pos - 1);
758 catch (BadLocationException e)
760 // FIXME: we're not authorized to throw this.. swallow it?
765 new TextAction(backwardAction)
767 public void actionPerformed(ActionEvent event)
769 JTextComponent t = getTextComponent(event);
772 t.getCaret().setDot(Math.max(t.getCaret().getDot() - 1,
773 t.getDocument().getStartPosition().getOffset()));
777 new TextAction(forwardAction)
779 public void actionPerformed(ActionEvent event)
781 JTextComponent t = getTextComponent(event);
784 t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
785 t.getDocument().getEndPosition().getOffset()));
789 new TextAction(selectionBackwardAction)
791 public void actionPerformed(ActionEvent event)
793 JTextComponent t = getTextComponent(event);
796 t.getCaret().moveDot(Math.max(t.getCaret().getDot() - 1,
797 t.getDocument().getStartPosition().getOffset()));
801 new TextAction(selectionForwardAction)
803 public void actionPerformed(ActionEvent event)
805 JTextComponent t = getTextComponent(event);
808 t.getCaret().moveDot(Math.min(t.getCaret().getDot() + 1,
809 t.getDocument().getEndPosition().getOffset()));
816 * Creates the <code>Caret</code> for this <code>EditorKit</code>. This
817 * returns a {@link DefaultCaret} in this case.
819 * @return the <code>Caret</code> for this <code>EditorKit</code>
821 public Caret createCaret()
823 return new DefaultCaret();
827 * Creates the default {@link Document} that this <code>EditorKit</code>
828 * supports. This is a {@link PlainDocument} in this case.
830 * @return the default {@link Document} that this <code>EditorKit</code>
833 public Document createDefaultDocument()
835 return new PlainDocument();
839 * Returns the <code>Action</code>s supported by this <code>EditorKit</code>.
841 * @return the <code>Action</code>s supported by this <code>EditorKit</code>
843 public Action[] getActions()
845 return defaultActions;
849 * Returns the content type that this <code>EditorKit</code> supports.
850 * The <code>DefaultEditorKit</code> supports the content type
851 * <code>text/plain</code>.
853 * @return the content type that this <code>EditorKit</code> supports
855 public String getContentType()
861 * Returns a {@link ViewFactory} that is able to create {@link View}s for
862 * the <code>Element</code>s that are used in this <code>EditorKit</code>'s
863 * model. This returns null which lets the UI of the text component supply
864 * <code>View</code>s.
866 * @return a {@link ViewFactory} that is able to create {@link View}s for
867 * the <code>Element</code>s that are used in this
868 * <code>EditorKit</code>'s model
870 public ViewFactory getViewFactory()
876 * Reads a document of the supported content type from an {@link InputStream}
877 * into the actual {@link Document} object.
879 * @param in the stream from which to read the document
880 * @param document the document model into which the content is read
881 * @param offset the offset inside to document where the content is inserted
883 * @throws BadLocationException if <code>offset</code> is an invalid location
884 * inside <code>document</code>
885 * @throws IOException if something goes wrong while reading from
888 public void read(InputStream in, Document document, int offset)
889 throws BadLocationException, IOException
891 read(new InputStreamReader(in), document, offset);
895 * Reads a document of the supported content type from a {@link Reader}
896 * into the actual {@link Document} object.
898 * @param in the reader from which to read the document
899 * @param document the document model into which the content is read
900 * @param offset the offset inside to document where the content is inserted
902 * @throws BadLocationException if <code>offset</code> is an invalid location
903 * inside <code>document</code>
904 * @throws IOException if something goes wrong while reading from
907 public void read(Reader in, Document document, int offset)
908 throws BadLocationException, IOException
910 BufferedReader reader = new BufferedReader(in);
913 StringBuffer content = new StringBuffer();
915 while ((line = reader.readLine()) != null)
917 content.append(line);
918 content.append("\n");
921 document.insertString(offset, content.toString(),
922 SimpleAttributeSet.EMPTY);
926 * Writes the <code>Document</code> (or a fragment of the
927 * <code>Document</code>) to an {@link OutputStream} in the
928 * supported content type format.
930 * @param out the stream to write to
931 * @param document the document that should be written out
932 * @param offset the beginning offset from where to write
933 * @param len the length of the fragment to write
935 * @throws BadLocationException if <code>offset</code> or
936 * <code>offset + len</code>is an invalid location inside
937 * <code>document</code>
938 * @throws IOException if something goes wrong while writing to
941 public void write(OutputStream out, Document document, int offset, int len)
942 throws BadLocationException, IOException
944 write(new OutputStreamWriter(out), document, offset, len);
948 * Writes the <code>Document</code> (or a fragment of the
949 * <code>Document</code>) to a {@link Writer} in the
950 * supported content type format.
952 * @param out the writer to write to
953 * @param document the document that should be written out
954 * @param offset the beginning offset from where to write
955 * @param len the length of the fragment to write
957 * @throws BadLocationException if <code>offset</code> or
958 * <code>offset + len</code>is an invalid location inside
959 * <code>document</code>
960 * @throws IOException if something goes wrong while writing to
963 public void write(Writer out, Document document, int offset, int len)
964 throws BadLocationException, IOException
966 // TODO: Implement this properly.