You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2313 lines
80 KiB
2313 lines
80 KiB
/*
|
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
package javax.swing.text;
|
|
|
|
import sun.awt.SunToolkit;
|
|
|
|
import java.io.*;
|
|
import java.awt.*;
|
|
import java.awt.event.ActionEvent;
|
|
import java.text.*;
|
|
import javax.swing.Action;
|
|
import javax.swing.KeyStroke;
|
|
import javax.swing.SwingConstants;
|
|
import javax.swing.UIManager;
|
|
|
|
/**
|
|
* This is the set of things needed by a text component
|
|
* to be a reasonably functioning editor for some <em>type</em>
|
|
* of text document. This implementation provides a default
|
|
* implementation which treats text as plain text and
|
|
* provides a minimal set of actions for a simple editor.
|
|
*
|
|
* <dl>
|
|
* <dt><b><font size=+1>Newlines</font></b>
|
|
* <dd>
|
|
* There are two properties which deal with newlines. The
|
|
* system property, <code>line.separator</code>, is defined to be
|
|
* platform-dependent, either "\n", "\r", or "\r\n". There is also
|
|
* a property defined in <code>DefaultEditorKit</code>, called
|
|
* <a href=#EndOfLineStringProperty><code>EndOfLineStringProperty</code></a>,
|
|
* which is defined automatically when a document is loaded, to be
|
|
* the first occurrence of any of the newline characters.
|
|
* When a document is loaded, <code>EndOfLineStringProperty</code>
|
|
* is set appropriately, and when the document is written back out, the
|
|
* <code>EndOfLineStringProperty</code> is used. But while the document
|
|
* is in memory, the "\n" character is used to define a
|
|
* newline, regardless of how the newline is defined when
|
|
* the document is on disk. Therefore, for searching purposes,
|
|
* "\n" should always be used. When a new document is created,
|
|
* and the <code>EndOfLineStringProperty</code> has not been defined,
|
|
* it will use the System property when writing out the
|
|
* document.
|
|
* <p>Note that <code>EndOfLineStringProperty</code> is set
|
|
* on the <code>Document</code> using the <code>get/putProperty</code>
|
|
* methods. Subclasses may override this behavior.
|
|
*
|
|
* </dl>
|
|
*
|
|
* @author Timothy Prinzing
|
|
*/
|
|
public class DefaultEditorKit extends EditorKit {
|
|
|
|
/**
|
|
* default constructor for DefaultEditorKit
|
|
*/
|
|
public DefaultEditorKit() {
|
|
}
|
|
|
|
/**
|
|
* Gets the MIME type of the data that this
|
|
* kit represents support for. The default
|
|
* is <code>text/plain</code>.
|
|
*
|
|
* @return the type
|
|
*/
|
|
public String getContentType() {
|
|
return "text/plain";
|
|
}
|
|
|
|
/**
|
|
* Fetches a factory that is suitable for producing
|
|
* views of any models that are produced by this
|
|
* kit. The default is to have the UI produce the
|
|
* factory, so this method has no implementation.
|
|
*
|
|
* @return the view factory
|
|
*/
|
|
public ViewFactory getViewFactory() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Fetches the set of commands that can be used
|
|
* on a text component that is using a model and
|
|
* view produced by this kit.
|
|
*
|
|
* @return the command list
|
|
*/
|
|
public Action[] getActions() {
|
|
return defaultActions.clone();
|
|
}
|
|
|
|
/**
|
|
* Fetches a caret that can navigate through views
|
|
* produced by the associated ViewFactory.
|
|
*
|
|
* @return the caret
|
|
*/
|
|
public Caret createCaret() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Creates an uninitialized text storage model (PlainDocument)
|
|
* that is appropriate for this type of editor.
|
|
*
|
|
* @return the model
|
|
*/
|
|
public Document createDefaultDocument() {
|
|
return new PlainDocument();
|
|
}
|
|
|
|
/**
|
|
* Inserts content from the given stream which is expected
|
|
* to be in a format appropriate for this kind of content
|
|
* handler.
|
|
*
|
|
* @param in The stream to read from
|
|
* @param doc The destination for the insertion.
|
|
* @param pos The location in the document to place the
|
|
* content >=0.
|
|
* @exception IOException on any I/O error
|
|
* @exception BadLocationException if pos represents an invalid
|
|
* location within the document.
|
|
*/
|
|
public void read(InputStream in, Document doc, int pos)
|
|
throws IOException, BadLocationException {
|
|
|
|
read(new InputStreamReader(in), doc, pos);
|
|
}
|
|
|
|
/**
|
|
* Writes content from a document to the given stream
|
|
* in a format appropriate for this kind of content handler.
|
|
*
|
|
* @param out The stream to write to
|
|
* @param doc The source for the write.
|
|
* @param pos The location in the document to fetch the
|
|
* content >=0.
|
|
* @param len The amount to write out >=0.
|
|
* @exception IOException on any I/O error
|
|
* @exception BadLocationException if pos represents an invalid
|
|
* location within the document.
|
|
*/
|
|
public void write(OutputStream out, Document doc, int pos, int len)
|
|
throws IOException, BadLocationException {
|
|
OutputStreamWriter osw = new OutputStreamWriter(out);
|
|
|
|
write(osw, doc, pos, len);
|
|
osw.flush();
|
|
}
|
|
|
|
/**
|
|
* Gets the input attributes for the pane. This method exists for
|
|
* the benefit of StyledEditorKit so that the read method will
|
|
* pick up the correct attributes to apply to inserted text.
|
|
* This class's implementation simply returns null.
|
|
*
|
|
* @return null
|
|
*/
|
|
MutableAttributeSet getInputAttributes() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Inserts content from the given stream, which will be
|
|
* treated as plain text.
|
|
*
|
|
* @param in The stream to read from
|
|
* @param doc The destination for the insertion.
|
|
* @param pos The location in the document to place the
|
|
* content >=0.
|
|
* @exception IOException on any I/O error
|
|
* @exception BadLocationException if pos represents an invalid
|
|
* location within the document.
|
|
*/
|
|
public void read(Reader in, Document doc, int pos)
|
|
throws IOException, BadLocationException {
|
|
|
|
char[] buff = new char[4096];
|
|
int nch;
|
|
boolean lastWasCR = false;
|
|
boolean isCRLF = false;
|
|
boolean isCR = false;
|
|
int last;
|
|
boolean wasEmpty = (doc.getLength() == 0);
|
|
AttributeSet attr = getInputAttributes();
|
|
|
|
// Read in a block at a time, mapping \r\n to \n, as well as single
|
|
// \r's to \n's. If a \r\n is encountered, \r\n will be set as the
|
|
// newline string for the document, if \r is encountered it will
|
|
// be set as the newline character, otherwise the newline property
|
|
// for the document will be removed.
|
|
while ((nch = in.read(buff, 0, buff.length)) != -1) {
|
|
last = 0;
|
|
for(int counter = 0; counter < nch; counter++) {
|
|
switch(buff[counter]) {
|
|
case '\r':
|
|
if (lastWasCR) {
|
|
isCR = true;
|
|
if (counter == 0) {
|
|
doc.insertString(pos, "\n", attr);
|
|
pos++;
|
|
}
|
|
else {
|
|
buff[counter - 1] = '\n';
|
|
}
|
|
}
|
|
else {
|
|
lastWasCR = true;
|
|
}
|
|
break;
|
|
case '\n':
|
|
if (lastWasCR) {
|
|
if (counter > (last + 1)) {
|
|
doc.insertString(pos, new String(buff, last,
|
|
counter - last - 1), attr);
|
|
pos += (counter - last - 1);
|
|
}
|
|
// else nothing to do, can skip \r, next write will
|
|
// write \n
|
|
lastWasCR = false;
|
|
last = counter;
|
|
isCRLF = true;
|
|
}
|
|
break;
|
|
default:
|
|
if (lastWasCR) {
|
|
isCR = true;
|
|
if (counter == 0) {
|
|
doc.insertString(pos, "\n", attr);
|
|
pos++;
|
|
}
|
|
else {
|
|
buff[counter - 1] = '\n';
|
|
}
|
|
lastWasCR = false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (last < nch) {
|
|
if(lastWasCR) {
|
|
if (last < (nch - 1)) {
|
|
doc.insertString(pos, new String(buff, last,
|
|
nch - last - 1), attr);
|
|
pos += (nch - last - 1);
|
|
}
|
|
}
|
|
else {
|
|
doc.insertString(pos, new String(buff, last,
|
|
nch - last), attr);
|
|
pos += (nch - last);
|
|
}
|
|
}
|
|
}
|
|
if (lastWasCR) {
|
|
doc.insertString(pos, "\n", attr);
|
|
isCR = true;
|
|
}
|
|
if (wasEmpty) {
|
|
if (isCRLF) {
|
|
doc.putProperty(EndOfLineStringProperty, "\r\n");
|
|
}
|
|
else if (isCR) {
|
|
doc.putProperty(EndOfLineStringProperty, "\r");
|
|
}
|
|
else {
|
|
doc.putProperty(EndOfLineStringProperty, "\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes content from a document to the given stream
|
|
* as plain text.
|
|
*
|
|
* @param out The stream to write to
|
|
* @param doc The source for the write.
|
|
* @param pos The location in the document to fetch the
|
|
* content from >=0.
|
|
* @param len The amount to write out >=0.
|
|
* @exception IOException on any I/O error
|
|
* @exception BadLocationException if pos is not within 0 and
|
|
* the length of the document.
|
|
*/
|
|
public void write(Writer out, Document doc, int pos, int len)
|
|
throws IOException, BadLocationException {
|
|
|
|
if ((pos < 0) || ((pos + len) > doc.getLength())) {
|
|
throw new BadLocationException("DefaultEditorKit.write", pos);
|
|
}
|
|
Segment data = new Segment();
|
|
int nleft = len;
|
|
int offs = pos;
|
|
Object endOfLineProperty = doc.getProperty(EndOfLineStringProperty);
|
|
if (endOfLineProperty == null) {
|
|
try {
|
|
endOfLineProperty = System.getProperty("line.separator");
|
|
} catch (SecurityException se) { }
|
|
}
|
|
String endOfLine;
|
|
if (endOfLineProperty instanceof String) {
|
|
endOfLine = (String)endOfLineProperty;
|
|
}
|
|
else {
|
|
endOfLine = null;
|
|
}
|
|
if (endOfLineProperty != null && !endOfLine.equals("\n")) {
|
|
// There is an end of line string that isn't \n, have to iterate
|
|
// through and find all \n's and translate to end of line string.
|
|
while (nleft > 0) {
|
|
int n = Math.min(nleft, 4096);
|
|
doc.getText(offs, n, data);
|
|
int last = data.offset;
|
|
char[] array = data.array;
|
|
int maxCounter = last + data.count;
|
|
for (int counter = last; counter < maxCounter; counter++) {
|
|
if (array[counter] == '\n') {
|
|
if (counter > last) {
|
|
out.write(array, last, counter - last);
|
|
}
|
|
out.write(endOfLine);
|
|
last = counter + 1;
|
|
}
|
|
}
|
|
if (maxCounter > last) {
|
|
out.write(array, last, maxCounter - last);
|
|
}
|
|
offs += n;
|
|
nleft -= n;
|
|
}
|
|
}
|
|
else {
|
|
// Just write out text, will already have \n, no mapping to
|
|
// do.
|
|
while (nleft > 0) {
|
|
int n = Math.min(nleft, 4096);
|
|
doc.getText(offs, n, data);
|
|
out.write(data.array, data.offset, data.count);
|
|
offs += n;
|
|
nleft -= n;
|
|
}
|
|
}
|
|
out.flush();
|
|
}
|
|
|
|
|
|
/**
|
|
* When reading a document if a CRLF is encountered a property
|
|
* with this name is added and the value will be "\r\n".
|
|
*/
|
|
public static final String EndOfLineStringProperty = "__EndOfLine__";
|
|
|
|
// --- names of well-known actions ---------------------------
|
|
|
|
/**
|
|
* Name of the action to place content into the associated
|
|
* document. If there is a selection, it is removed before
|
|
* the new content is added.
|
|
* @see #getActions
|
|
*/
|
|
public static final String insertContentAction = "insert-content";
|
|
|
|
/**
|
|
* Name of the action to place a line/paragraph break into
|
|
* the document. If there is a selection, it is removed before
|
|
* the break is added.
|
|
* @see #getActions
|
|
*/
|
|
public static final String insertBreakAction = "insert-break";
|
|
|
|
/**
|
|
* Name of the action to place a tab character into
|
|
* the document. If there is a selection, it is removed before
|
|
* the tab is added.
|
|
* @see #getActions
|
|
*/
|
|
public static final String insertTabAction = "insert-tab";
|
|
|
|
/**
|
|
* Name of the action to delete the character of content that
|
|
* precedes the current caret position.
|
|
* @see #getActions
|
|
*/
|
|
public static final String deletePrevCharAction = "delete-previous";
|
|
|
|
/**
|
|
* Name of the action to delete the character of content that
|
|
* follows the current caret position.
|
|
* @see #getActions
|
|
*/
|
|
public static final String deleteNextCharAction = "delete-next";
|
|
|
|
/**
|
|
* Name of the action to delete the word that
|
|
* follows the beginning of the selection.
|
|
* @see #getActions
|
|
* @see JTextComponent#getSelectionStart
|
|
* @since 1.6
|
|
*/
|
|
public static final String deleteNextWordAction = "delete-next-word";
|
|
|
|
/**
|
|
* Name of the action to delete the word that
|
|
* precedes the beginning of the selection.
|
|
* @see #getActions
|
|
* @see JTextComponent#getSelectionStart
|
|
* @since 1.6
|
|
*/
|
|
public static final String deletePrevWordAction = "delete-previous-word";
|
|
|
|
/**
|
|
* Name of the action to set the editor into read-only
|
|
* mode.
|
|
* @see #getActions
|
|
*/
|
|
public static final String readOnlyAction = "set-read-only";
|
|
|
|
/**
|
|
* Name of the action to set the editor into writeable
|
|
* mode.
|
|
* @see #getActions
|
|
*/
|
|
public static final String writableAction = "set-writable";
|
|
|
|
/**
|
|
* Name of the action to cut the selected region
|
|
* and place the contents into the system clipboard.
|
|
* @see JTextComponent#cut
|
|
* @see #getActions
|
|
*/
|
|
public static final String cutAction = "cut-to-clipboard";
|
|
|
|
/**
|
|
* Name of the action to copy the selected region
|
|
* and place the contents into the system clipboard.
|
|
* @see JTextComponent#copy
|
|
* @see #getActions
|
|
*/
|
|
public static final String copyAction = "copy-to-clipboard";
|
|
|
|
/**
|
|
* Name of the action to paste the contents of the
|
|
* system clipboard into the selected region, or before the
|
|
* caret if nothing is selected.
|
|
* @see JTextComponent#paste
|
|
* @see #getActions
|
|
*/
|
|
public static final String pasteAction = "paste-from-clipboard";
|
|
|
|
/**
|
|
* Name of the action to create a beep.
|
|
* @see #getActions
|
|
*/
|
|
public static final String beepAction = "beep";
|
|
|
|
/**
|
|
* Name of the action to page up vertically.
|
|
* @see #getActions
|
|
*/
|
|
public static final String pageUpAction = "page-up";
|
|
|
|
/**
|
|
* Name of the action to page down vertically.
|
|
* @see #getActions
|
|
*/
|
|
public static final String pageDownAction = "page-down";
|
|
|
|
/**
|
|
* Name of the action to page up vertically, and move the
|
|
* selection.
|
|
* @see #getActions
|
|
*/
|
|
/*public*/ static final String selectionPageUpAction = "selection-page-up";
|
|
|
|
/**
|
|
* Name of the action to page down vertically, and move the
|
|
* selection.
|
|
* @see #getActions
|
|
*/
|
|
/*public*/ static final String selectionPageDownAction = "selection-page-down";
|
|
|
|
/**
|
|
* Name of the action to page left horizontally, and move the
|
|
* selection.
|
|
* @see #getActions
|
|
*/
|
|
/*public*/ static final String selectionPageLeftAction = "selection-page-left";
|
|
|
|
/**
|
|
* Name of the action to page right horizontally, and move the
|
|
* selection.
|
|
* @see #getActions
|
|
*/
|
|
/*public*/ static final String selectionPageRightAction = "selection-page-right";
|
|
|
|
/**
|
|
* Name of the Action for moving the caret
|
|
* logically forward one position.
|
|
* @see #getActions
|
|
*/
|
|
public static final String forwardAction = "caret-forward";
|
|
|
|
/**
|
|
* Name of the Action for moving the caret
|
|
* logically backward one position.
|
|
* @see #getActions
|
|
*/
|
|
public static final String backwardAction = "caret-backward";
|
|
|
|
/**
|
|
* Name of the Action for extending the selection
|
|
* by moving the caret logically forward one position.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionForwardAction = "selection-forward";
|
|
|
|
/**
|
|
* Name of the Action for extending the selection
|
|
* by moving the caret logically backward one position.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionBackwardAction = "selection-backward";
|
|
|
|
/**
|
|
* Name of the Action for moving the caret
|
|
* logically upward one position.
|
|
* @see #getActions
|
|
*/
|
|
public static final String upAction = "caret-up";
|
|
|
|
/**
|
|
* Name of the Action for moving the caret
|
|
* logically downward one position.
|
|
* @see #getActions
|
|
*/
|
|
public static final String downAction = "caret-down";
|
|
|
|
/**
|
|
* Name of the Action for moving the caret
|
|
* logically upward one position, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionUpAction = "selection-up";
|
|
|
|
/**
|
|
* Name of the Action for moving the caret
|
|
* logically downward one position, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionDownAction = "selection-down";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the beginning of a word.
|
|
* @see #getActions
|
|
*/
|
|
public static final String beginWordAction = "caret-begin-word";
|
|
|
|
/**
|
|
* Name of the Action for moving the caret
|
|
* to the end of a word.
|
|
* @see #getActions
|
|
*/
|
|
public static final String endWordAction = "caret-end-word";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the beginning of a word, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionBeginWordAction = "selection-begin-word";
|
|
|
|
/**
|
|
* Name of the Action for moving the caret
|
|
* to the end of a word, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionEndWordAction = "selection-end-word";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret to the
|
|
* beginning of the previous word.
|
|
* @see #getActions
|
|
*/
|
|
public static final String previousWordAction = "caret-previous-word";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret to the
|
|
* beginning of the next word.
|
|
* @see #getActions
|
|
*/
|
|
public static final String nextWordAction = "caret-next-word";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the selection to the
|
|
* beginning of the previous word, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionPreviousWordAction = "selection-previous-word";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the selection to the
|
|
* beginning of the next word, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionNextWordAction = "selection-next-word";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the beginning of a line.
|
|
* @see #getActions
|
|
*/
|
|
public static final String beginLineAction = "caret-begin-line";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the end of a line.
|
|
* @see #getActions
|
|
*/
|
|
public static final String endLineAction = "caret-end-line";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the beginning of a line, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionBeginLineAction = "selection-begin-line";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the end of a line, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionEndLineAction = "selection-end-line";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the beginning of a paragraph.
|
|
* @see #getActions
|
|
*/
|
|
public static final String beginParagraphAction = "caret-begin-paragraph";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the end of a paragraph.
|
|
* @see #getActions
|
|
*/
|
|
public static final String endParagraphAction = "caret-end-paragraph";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the beginning of a paragraph, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionBeginParagraphAction = "selection-begin-paragraph";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the end of a paragraph, extending the selection.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionEndParagraphAction = "selection-end-paragraph";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the beginning of the document.
|
|
* @see #getActions
|
|
*/
|
|
public static final String beginAction = "caret-begin";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the end of the document.
|
|
* @see #getActions
|
|
*/
|
|
public static final String endAction = "caret-end";
|
|
|
|
/**
|
|
* Name of the <code>Action</code> for moving the caret
|
|
* to the beginning of the document.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionBeginAction = "selection-begin";
|
|
|
|
/**
|
|
* Name of the Action for moving the caret
|
|
* to the end of the document.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectionEndAction = "selection-end";
|
|
|
|
/**
|
|
* Name of the Action for selecting a word around the caret.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectWordAction = "select-word";
|
|
|
|
/**
|
|
* Name of the Action for selecting a line around the caret.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectLineAction = "select-line";
|
|
|
|
/**
|
|
* Name of the Action for selecting a paragraph around the caret.
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectParagraphAction = "select-paragraph";
|
|
|
|
/**
|
|
* Name of the Action for selecting the entire document
|
|
* @see #getActions
|
|
*/
|
|
public static final String selectAllAction = "select-all";
|
|
|
|
/**
|
|
* Name of the Action for removing selection
|
|
* @see #getActions
|
|
*/
|
|
/*public*/ static final String unselectAction = "unselect";
|
|
|
|
/**
|
|
* Name of the Action for toggling the component's orientation.
|
|
* @see #getActions
|
|
*/
|
|
/*public*/ static final String toggleComponentOrientationAction
|
|
= "toggle-componentOrientation";
|
|
|
|
/**
|
|
* Name of the action that is executed by default if
|
|
* a <em>key typed event</em> is received and there
|
|
* is no keymap entry.
|
|
* @see #getActions
|
|
*/
|
|
public static final String defaultKeyTypedAction = "default-typed";
|
|
|
|
// --- Action implementations ---------------------------------
|
|
|
|
private static final Action[] defaultActions = {
|
|
new InsertContentAction(), new DeletePrevCharAction(),
|
|
new DeleteNextCharAction(), new ReadOnlyAction(),
|
|
new DeleteWordAction(deletePrevWordAction),
|
|
new DeleteWordAction(deleteNextWordAction),
|
|
new WritableAction(), new CutAction(),
|
|
new CopyAction(), new PasteAction(),
|
|
new VerticalPageAction(pageUpAction, -1, false),
|
|
new VerticalPageAction(pageDownAction, 1, false),
|
|
new VerticalPageAction(selectionPageUpAction, -1, true),
|
|
new VerticalPageAction(selectionPageDownAction, 1, true),
|
|
new PageAction(selectionPageLeftAction, true, true),
|
|
new PageAction(selectionPageRightAction, false, true),
|
|
new InsertBreakAction(), new BeepAction(),
|
|
new NextVisualPositionAction(forwardAction, false,
|
|
SwingConstants.EAST),
|
|
new NextVisualPositionAction(backwardAction, false,
|
|
SwingConstants.WEST),
|
|
new NextVisualPositionAction(selectionForwardAction, true,
|
|
SwingConstants.EAST),
|
|
new NextVisualPositionAction(selectionBackwardAction, true,
|
|
SwingConstants.WEST),
|
|
new NextVisualPositionAction(upAction, false,
|
|
SwingConstants.NORTH),
|
|
new NextVisualPositionAction(downAction, false,
|
|
SwingConstants.SOUTH),
|
|
new NextVisualPositionAction(selectionUpAction, true,
|
|
SwingConstants.NORTH),
|
|
new NextVisualPositionAction(selectionDownAction, true,
|
|
SwingConstants.SOUTH),
|
|
new BeginWordAction(beginWordAction, false),
|
|
new EndWordAction(endWordAction, false),
|
|
new BeginWordAction(selectionBeginWordAction, true),
|
|
new EndWordAction(selectionEndWordAction, true),
|
|
new PreviousWordAction(previousWordAction, false),
|
|
new NextWordAction(nextWordAction, false),
|
|
new PreviousWordAction(selectionPreviousWordAction, true),
|
|
new NextWordAction(selectionNextWordAction, true),
|
|
new BeginLineAction(beginLineAction, false),
|
|
new EndLineAction(endLineAction, false),
|
|
new BeginLineAction(selectionBeginLineAction, true),
|
|
new EndLineAction(selectionEndLineAction, true),
|
|
new BeginParagraphAction(beginParagraphAction, false),
|
|
new EndParagraphAction(endParagraphAction, false),
|
|
new BeginParagraphAction(selectionBeginParagraphAction, true),
|
|
new EndParagraphAction(selectionEndParagraphAction, true),
|
|
new BeginAction(beginAction, false),
|
|
new EndAction(endAction, false),
|
|
new BeginAction(selectionBeginAction, true),
|
|
new EndAction(selectionEndAction, true),
|
|
new DefaultKeyTypedAction(), new InsertTabAction(),
|
|
new SelectWordAction(), new SelectLineAction(),
|
|
new SelectParagraphAction(), new SelectAllAction(),
|
|
new UnselectAction(), new ToggleComponentOrientationAction(),
|
|
new DumpModelAction()
|
|
};
|
|
|
|
/**
|
|
* The action that is executed by default if
|
|
* a <em>key typed event</em> is received and there
|
|
* is no keymap entry. There is a variation across
|
|
* different VM's in what gets sent as a <em>key typed</em>
|
|
* event, and this action tries to filter out the undesired
|
|
* events. This filters the control characters and those
|
|
* with the ALT modifier. It allows Control-Alt sequences
|
|
* through as these form legitimate unicode characters on
|
|
* some PC keyboards.
|
|
* <p>
|
|
* If the event doesn't get filtered, it will try to insert
|
|
* content into the text editor. The content is fetched
|
|
* from the command string of the ActionEvent. The text
|
|
* entry is done through the <code>replaceSelection</code>
|
|
* method on the target text component. This is the
|
|
* action that will be fired for most text entry tasks.
|
|
* <p>
|
|
* <strong>Warning:</strong>
|
|
* Serialized objects of this class will not be compatible with
|
|
* future Swing releases. The current serialization support is
|
|
* appropriate for short term storage or RMI between applications running
|
|
* the same version of Swing. As of 1.4, support for long term storage
|
|
* of all JavaBeans™
|
|
* has been added to the <code>java.beans</code> package.
|
|
* Please see {@link java.beans.XMLEncoder}.
|
|
*
|
|
* @see DefaultEditorKit#defaultKeyTypedAction
|
|
* @see DefaultEditorKit#getActions
|
|
* @see Keymap#setDefaultAction
|
|
* @see Keymap#getDefaultAction
|
|
*/
|
|
public static class DefaultKeyTypedAction extends TextAction {
|
|
|
|
/**
|
|
* Creates this object with the appropriate identifier.
|
|
*/
|
|
public DefaultKeyTypedAction() {
|
|
super(defaultKeyTypedAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if ((target != null) && (e != null)) {
|
|
if ((! target.isEditable()) || (! target.isEnabled())) {
|
|
return;
|
|
}
|
|
String content = e.getActionCommand();
|
|
int mod = e.getModifiers();
|
|
if ((content != null) && (content.length() > 0)) {
|
|
boolean isPrintableMask = true;
|
|
Toolkit tk = Toolkit.getDefaultToolkit();
|
|
if (tk instanceof SunToolkit) {
|
|
isPrintableMask = ((SunToolkit)tk).isPrintableCharacterModifiersMask(mod);
|
|
}
|
|
|
|
if (isPrintableMask) {
|
|
char c = content.charAt(0);
|
|
if ((c >= 0x20) && (c != 0x7F)) {
|
|
target.replaceSelection(content);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Places content into the associated document.
|
|
* If there is a selection, it is removed before
|
|
* the new content is added.
|
|
* <p>
|
|
* <strong>Warning:</strong>
|
|
* Serialized objects of this class will not be compatible with
|
|
* future Swing releases. The current serialization support is
|
|
* appropriate for short term storage or RMI between applications running
|
|
* the same version of Swing. As of 1.4, support for long term storage
|
|
* of all JavaBeans™
|
|
* has been added to the <code>java.beans</code> package.
|
|
* Please see {@link java.beans.XMLEncoder}.
|
|
*
|
|
* @see DefaultEditorKit#insertContentAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
public static class InsertContentAction extends TextAction {
|
|
|
|
/**
|
|
* Creates this object with the appropriate identifier.
|
|
*/
|
|
public InsertContentAction() {
|
|
super(insertContentAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if ((target != null) && (e != null)) {
|
|
if ((! target.isEditable()) || (! target.isEnabled())) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
return;
|
|
}
|
|
String content = e.getActionCommand();
|
|
if (content != null) {
|
|
target.replaceSelection(content);
|
|
} else {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Places a line/paragraph break into the document.
|
|
* If there is a selection, it is removed before
|
|
* the break is added.
|
|
* <p>
|
|
* <strong>Warning:</strong>
|
|
* Serialized objects of this class will not be compatible with
|
|
* future Swing releases. The current serialization support is
|
|
* appropriate for short term storage or RMI between applications running
|
|
* the same version of Swing. As of 1.4, support for long term storage
|
|
* of all JavaBeans™
|
|
* has been added to the <code>java.beans</code> package.
|
|
* Please see {@link java.beans.XMLEncoder}.
|
|
*
|
|
* @see DefaultEditorKit#insertBreakAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
public static class InsertBreakAction extends TextAction {
|
|
|
|
/**
|
|
* Creates this object with the appropriate identifier.
|
|
*/
|
|
public InsertBreakAction() {
|
|
super(insertBreakAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
if ((! target.isEditable()) || (! target.isEnabled())) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
return;
|
|
}
|
|
target.replaceSelection("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Places a tab character into the document. If there
|
|
* is a selection, it is removed before the tab is added.
|
|
* <p>
|
|
* <strong>Warning:</strong>
|
|
* Serialized objects of this class will not be compatible with
|
|
* future Swing releases. The current serialization support is
|
|
* appropriate for short term storage or RMI between applications running
|
|
* the same version of Swing. As of 1.4, support for long term storage
|
|
* of all JavaBeans™
|
|
* has been added to the <code>java.beans</code> package.
|
|
* Please see {@link java.beans.XMLEncoder}.
|
|
*
|
|
* @see DefaultEditorKit#insertTabAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
public static class InsertTabAction extends TextAction {
|
|
|
|
/**
|
|
* Creates this object with the appropriate identifier.
|
|
*/
|
|
public InsertTabAction() {
|
|
super(insertTabAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
if ((! target.isEditable()) || (! target.isEnabled())) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
return;
|
|
}
|
|
target.replaceSelection("\t");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Deletes the character of content that precedes the
|
|
* current caret position.
|
|
* @see DefaultEditorKit#deletePrevCharAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class DeletePrevCharAction extends TextAction {
|
|
|
|
/**
|
|
* Creates this object with the appropriate identifier.
|
|
*/
|
|
DeletePrevCharAction() {
|
|
super(deletePrevCharAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
boolean beep = true;
|
|
if ((target != null) && (target.isEditable())) {
|
|
try {
|
|
Document doc = target.getDocument();
|
|
Caret caret = target.getCaret();
|
|
int dot = caret.getDot();
|
|
int mark = caret.getMark();
|
|
if (dot != mark) {
|
|
doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
|
|
beep = false;
|
|
} else if (dot > 0) {
|
|
int delChars = 1;
|
|
|
|
if (dot > 1) {
|
|
String dotChars = doc.getText(dot - 2, 2);
|
|
char c0 = dotChars.charAt(0);
|
|
char c1 = dotChars.charAt(1);
|
|
|
|
if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
|
|
c1 >= '\uDC00' && c1 <= '\uDFFF') {
|
|
delChars = 2;
|
|
}
|
|
}
|
|
|
|
doc.remove(dot - delChars, delChars);
|
|
beep = false;
|
|
}
|
|
} catch (BadLocationException bl) {
|
|
}
|
|
}
|
|
if (beep) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Deletes the character of content that follows the
|
|
* current caret position.
|
|
* @see DefaultEditorKit#deleteNextCharAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class DeleteNextCharAction extends TextAction {
|
|
|
|
/* Create this object with the appropriate identifier. */
|
|
DeleteNextCharAction() {
|
|
super(deleteNextCharAction);
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
boolean beep = true;
|
|
if ((target != null) && (target.isEditable())) {
|
|
try {
|
|
Document doc = target.getDocument();
|
|
Caret caret = target.getCaret();
|
|
int dot = caret.getDot();
|
|
int mark = caret.getMark();
|
|
if (dot != mark) {
|
|
doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
|
|
beep = false;
|
|
} else if (dot < doc.getLength()) {
|
|
int delChars = 1;
|
|
|
|
if (dot < doc.getLength() - 1) {
|
|
String dotChars = doc.getText(dot, 2);
|
|
char c0 = dotChars.charAt(0);
|
|
char c1 = dotChars.charAt(1);
|
|
|
|
if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
|
|
c1 >= '\uDC00' && c1 <= '\uDFFF') {
|
|
delChars = 2;
|
|
}
|
|
}
|
|
|
|
doc.remove(dot, delChars);
|
|
beep = false;
|
|
}
|
|
} catch (BadLocationException bl) {
|
|
}
|
|
}
|
|
if (beep) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Deletes the word that precedes/follows the beginning of the selection.
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class DeleteWordAction extends TextAction {
|
|
DeleteWordAction(String name) {
|
|
super(name);
|
|
assert (name == deletePrevWordAction)
|
|
|| (name == deleteNextWordAction);
|
|
}
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
final JTextComponent target = getTextComponent(e);
|
|
if ((target != null) && (e != null)) {
|
|
if ((! target.isEditable()) || (! target.isEnabled())) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
return;
|
|
}
|
|
boolean beep = true;
|
|
try {
|
|
final int start = target.getSelectionStart();
|
|
final Element line =
|
|
Utilities.getParagraphElement(target, start);
|
|
int end;
|
|
if (deleteNextWordAction == getValue(Action.NAME)) {
|
|
end = Utilities.
|
|
getNextWordInParagraph(target, line, start, false);
|
|
if (end == java.text.BreakIterator.DONE) {
|
|
//last word in the paragraph
|
|
final int endOfLine = line.getEndOffset();
|
|
if (start == endOfLine - 1) {
|
|
//for last position remove last \n
|
|
end = endOfLine;
|
|
} else {
|
|
//remove to the end of the paragraph
|
|
end = endOfLine - 1;
|
|
}
|
|
}
|
|
} else {
|
|
end = Utilities.
|
|
getPrevWordInParagraph(target, line, start);
|
|
if (end == java.text.BreakIterator.DONE) {
|
|
//there is no previous word in the paragraph
|
|
final int startOfLine = line.getStartOffset();
|
|
if (start == startOfLine) {
|
|
//for first position remove previous \n
|
|
end = startOfLine - 1;
|
|
} else {
|
|
//remove to the start of the paragraph
|
|
end = startOfLine;
|
|
}
|
|
}
|
|
}
|
|
int offs = Math.min(start, end);
|
|
int len = Math.abs(end - start);
|
|
if (offs >= 0) {
|
|
target.getDocument().remove(offs, len);
|
|
beep = false;
|
|
}
|
|
} catch (BadLocationException ignore) {
|
|
}
|
|
if (beep) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Sets the editor into read-only mode.
|
|
* @see DefaultEditorKit#readOnlyAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class ReadOnlyAction extends TextAction {
|
|
|
|
/* Create this object with the appropriate identifier. */
|
|
ReadOnlyAction() {
|
|
super(readOnlyAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
target.setEditable(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Sets the editor into writeable mode.
|
|
* @see DefaultEditorKit#writableAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class WritableAction extends TextAction {
|
|
|
|
/* Create this object with the appropriate identifier. */
|
|
WritableAction() {
|
|
super(writableAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
target.setEditable(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cuts the selected region and place its contents
|
|
* into the system clipboard.
|
|
* <p>
|
|
* <strong>Warning:</strong>
|
|
* Serialized objects of this class will not be compatible with
|
|
* future Swing releases. The current serialization support is
|
|
* appropriate for short term storage or RMI between applications running
|
|
* the same version of Swing. As of 1.4, support for long term storage
|
|
* of all JavaBeans™
|
|
* has been added to the <code>java.beans</code> package.
|
|
* Please see {@link java.beans.XMLEncoder}.
|
|
*
|
|
* @see DefaultEditorKit#cutAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
public static class CutAction extends TextAction {
|
|
|
|
/** Create this object with the appropriate identifier. */
|
|
public CutAction() {
|
|
super(cutAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
target.cut();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Copies the selected region and place its contents
|
|
* into the system clipboard.
|
|
* <p>
|
|
* <strong>Warning:</strong>
|
|
* Serialized objects of this class will not be compatible with
|
|
* future Swing releases. The current serialization support is
|
|
* appropriate for short term storage or RMI between applications running
|
|
* the same version of Swing. As of 1.4, support for long term storage
|
|
* of all JavaBeans™
|
|
* has been added to the <code>java.beans</code> package.
|
|
* Please see {@link java.beans.XMLEncoder}.
|
|
*
|
|
* @see DefaultEditorKit#copyAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
public static class CopyAction extends TextAction {
|
|
|
|
/** Create this object with the appropriate identifier. */
|
|
public CopyAction() {
|
|
super(copyAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
target.copy();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Pastes the contents of the system clipboard into the
|
|
* selected region, or before the caret if nothing is
|
|
* selected.
|
|
* <p>
|
|
* <strong>Warning:</strong>
|
|
* Serialized objects of this class will not be compatible with
|
|
* future Swing releases. The current serialization support is
|
|
* appropriate for short term storage or RMI between applications running
|
|
* the same version of Swing. As of 1.4, support for long term storage
|
|
* of all JavaBeans™
|
|
* has been added to the <code>java.beans</code> package.
|
|
* Please see {@link java.beans.XMLEncoder}.
|
|
*
|
|
* @see DefaultEditorKit#pasteAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
public static class PasteAction extends TextAction {
|
|
|
|
/** Create this object with the appropriate identifier. */
|
|
public PasteAction() {
|
|
super(pasteAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
target.paste();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a beep.
|
|
* <p>
|
|
* <strong>Warning:</strong>
|
|
* Serialized objects of this class will not be compatible with
|
|
* future Swing releases. The current serialization support is
|
|
* appropriate for short term storage or RMI between applications running
|
|
* the same version of Swing. As of 1.4, support for long term storage
|
|
* of all JavaBeans™
|
|
* has been added to the <code>java.beans</code> package.
|
|
* Please see {@link java.beans.XMLEncoder}.
|
|
*
|
|
* @see DefaultEditorKit#beepAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
public static class BeepAction extends TextAction {
|
|
|
|
/** Create this object with the appropriate identifier. */
|
|
public BeepAction() {
|
|
super(beepAction);
|
|
}
|
|
|
|
/**
|
|
* The operation to perform when this action is triggered.
|
|
*
|
|
* @param e the action event
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Scrolls up/down vertically. The select version of this action extends
|
|
* the selection, instead of simply moving the caret.
|
|
*
|
|
* @see DefaultEditorKit#pageUpAction
|
|
* @see DefaultEditorKit#pageDownAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class VerticalPageAction extends TextAction {
|
|
|
|
/** Create this object with the appropriate identifier. */
|
|
public VerticalPageAction(String nm, int direction, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
this.direction = direction;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
Rectangle visible = target.getVisibleRect();
|
|
Rectangle newVis = new Rectangle(visible);
|
|
int selectedIndex = target.getCaretPosition();
|
|
int scrollAmount = direction *
|
|
target.getScrollableBlockIncrement(
|
|
visible, SwingConstants.VERTICAL, direction);
|
|
int initialY = visible.y;
|
|
Caret caret = target.getCaret();
|
|
Point magicPosition = caret.getMagicCaretPosition();
|
|
|
|
if (selectedIndex != -1) {
|
|
try {
|
|
Rectangle dotBounds = target.modelToView(
|
|
selectedIndex);
|
|
int x = (magicPosition != null) ? magicPosition.x :
|
|
dotBounds.x;
|
|
int h = dotBounds.height;
|
|
if (h > 0) {
|
|
// We want to scroll by a multiple of caret height,
|
|
// rounding towards lower integer
|
|
scrollAmount = scrollAmount / h * h;
|
|
}
|
|
newVis.y = constrainY(target,
|
|
initialY + scrollAmount, visible.height);
|
|
|
|
int newIndex;
|
|
|
|
if (visible.contains(dotBounds.x, dotBounds.y)) {
|
|
// Dot is currently visible, base the new
|
|
// location off the old, or
|
|
newIndex = target.viewToModel(
|
|
new Point(x, constrainY(target,
|
|
dotBounds.y + scrollAmount, 0)));
|
|
}
|
|
else {
|
|
// Dot isn't visible, choose the top or the bottom
|
|
// for the new location.
|
|
if (direction == -1) {
|
|
newIndex = target.viewToModel(new Point(
|
|
x, newVis.y));
|
|
}
|
|
else {
|
|
newIndex = target.viewToModel(new Point(
|
|
x, newVis.y + visible.height));
|
|
}
|
|
}
|
|
newIndex = constrainOffset(target, newIndex);
|
|
if (newIndex != selectedIndex) {
|
|
// Make sure the new visible location contains
|
|
// the location of dot, otherwise Caret will
|
|
// cause an additional scroll.
|
|
int newY = getAdjustedY(target, newVis, newIndex);
|
|
|
|
if (direction == -1 && newY <= initialY || direction == 1 && newY >= initialY) {
|
|
// Change index and correct newVis.y only if won't cause scrolling upward
|
|
newVis.y = newY;
|
|
|
|
if (select) {
|
|
target.moveCaretPosition(newIndex);
|
|
} else {
|
|
target.setCaretPosition(newIndex);
|
|
}
|
|
}
|
|
}
|
|
} catch (BadLocationException ble) { }
|
|
} else {
|
|
newVis.y = constrainY(target,
|
|
initialY + scrollAmount, visible.height);
|
|
}
|
|
if (magicPosition != null) {
|
|
caret.setMagicCaretPosition(magicPosition);
|
|
}
|
|
target.scrollRectToVisible(newVis);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Makes sure <code>y</code> is a valid location in
|
|
* <code>target</code>.
|
|
*/
|
|
private int constrainY(JTextComponent target, int y, int vis) {
|
|
if (y < 0) {
|
|
y = 0;
|
|
}
|
|
else if (y + vis > target.getHeight()) {
|
|
y = Math.max(0, target.getHeight() - vis);
|
|
}
|
|
return y;
|
|
}
|
|
|
|
/**
|
|
* Ensures that <code>offset</code> is a valid offset into the
|
|
* model for <code>text</code>.
|
|
*/
|
|
private int constrainOffset(JTextComponent text, int offset) {
|
|
Document doc = text.getDocument();
|
|
|
|
if ((offset != 0) && (offset > doc.getLength())) {
|
|
offset = doc.getLength();
|
|
}
|
|
if (offset < 0) {
|
|
offset = 0;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/**
|
|
* Returns adjustsed {@code y} position that indicates the location to scroll to
|
|
* after selecting <code>index</code>.
|
|
*/
|
|
private int getAdjustedY(JTextComponent text, Rectangle visible, int index) {
|
|
int result = visible.y;
|
|
|
|
try {
|
|
Rectangle dotBounds = text.modelToView(index);
|
|
|
|
if (dotBounds.y < visible.y) {
|
|
result = dotBounds.y;
|
|
} else {
|
|
if ((dotBounds.y > visible.y + visible.height) ||
|
|
(dotBounds.y + dotBounds.height > visible.y + visible.height)) {
|
|
result = dotBounds.y + dotBounds.height - visible.height;
|
|
}
|
|
}
|
|
} catch (BadLocationException ble) {
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Adjusts the Rectangle to contain the bounds of the character at
|
|
* <code>index</code> in response to a page up.
|
|
*/
|
|
private boolean select;
|
|
|
|
/**
|
|
* Direction to scroll, 1 is down, -1 is up.
|
|
*/
|
|
private int direction;
|
|
}
|
|
|
|
|
|
/**
|
|
* Pages one view to the left or right.
|
|
*/
|
|
static class PageAction extends TextAction {
|
|
|
|
/** Create this object with the appropriate identifier. */
|
|
public PageAction(String nm, boolean left, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
this.left = left;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
int selectedIndex;
|
|
Rectangle visible = new Rectangle();
|
|
target.computeVisibleRect(visible);
|
|
if (left) {
|
|
visible.x = Math.max(0, visible.x - visible.width);
|
|
}
|
|
else {
|
|
visible.x += visible.width;
|
|
}
|
|
|
|
selectedIndex = target.getCaretPosition();
|
|
if(selectedIndex != -1) {
|
|
if (left) {
|
|
selectedIndex = target.viewToModel
|
|
(new Point(visible.x, visible.y));
|
|
}
|
|
else {
|
|
selectedIndex = target.viewToModel
|
|
(new Point(visible.x + visible.width - 1,
|
|
visible.y + visible.height - 1));
|
|
}
|
|
Document doc = target.getDocument();
|
|
if ((selectedIndex != 0) &&
|
|
(selectedIndex > (doc.getLength()-1))) {
|
|
selectedIndex = doc.getLength()-1;
|
|
}
|
|
else if(selectedIndex < 0) {
|
|
selectedIndex = 0;
|
|
}
|
|
if (select)
|
|
target.moveCaretPosition(selectedIndex);
|
|
else
|
|
target.setCaretPosition(selectedIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
private boolean left;
|
|
}
|
|
|
|
static class DumpModelAction extends TextAction {
|
|
|
|
DumpModelAction() {
|
|
super("dump-model");
|
|
}
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
Document d = target.getDocument();
|
|
if (d instanceof AbstractDocument) {
|
|
((AbstractDocument) d).dump(System.err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Action to move the selection by way of the
|
|
* getNextVisualPositionFrom method. Constructor indicates direction
|
|
* to use.
|
|
*/
|
|
static class NextVisualPositionAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
NextVisualPositionAction(String nm, boolean select, int direction) {
|
|
super(nm);
|
|
this.select = select;
|
|
this.direction = direction;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
Caret caret = target.getCaret();
|
|
DefaultCaret bidiCaret = (caret instanceof DefaultCaret) ?
|
|
(DefaultCaret)caret : null;
|
|
int dot = caret.getDot();
|
|
Position.Bias[] bias = new Position.Bias[1];
|
|
Point magicPosition = caret.getMagicCaretPosition();
|
|
|
|
try {
|
|
if(magicPosition == null &&
|
|
(direction == SwingConstants.NORTH ||
|
|
direction == SwingConstants.SOUTH)) {
|
|
Rectangle r = (bidiCaret != null) ?
|
|
target.getUI().modelToView(target, dot,
|
|
bidiCaret.getDotBias()) :
|
|
target.modelToView(dot);
|
|
magicPosition = new Point(r.x, r.y);
|
|
}
|
|
|
|
NavigationFilter filter = target.getNavigationFilter();
|
|
|
|
if (filter != null) {
|
|
dot = filter.getNextVisualPositionFrom
|
|
(target, dot, (bidiCaret != null) ?
|
|
bidiCaret.getDotBias() :
|
|
Position.Bias.Forward, direction, bias);
|
|
}
|
|
else {
|
|
dot = target.getUI().getNextVisualPositionFrom
|
|
(target, dot, (bidiCaret != null) ?
|
|
bidiCaret.getDotBias() :
|
|
Position.Bias.Forward, direction, bias);
|
|
}
|
|
if(bias[0] == null) {
|
|
bias[0] = Position.Bias.Forward;
|
|
}
|
|
if(bidiCaret != null) {
|
|
if (select) {
|
|
bidiCaret.moveDot(dot, bias[0]);
|
|
} else {
|
|
bidiCaret.setDot(dot, bias[0]);
|
|
}
|
|
}
|
|
else {
|
|
if (select) {
|
|
caret.moveDot(dot);
|
|
} else {
|
|
caret.setDot(dot);
|
|
}
|
|
}
|
|
if(magicPosition != null &&
|
|
(direction == SwingConstants.NORTH ||
|
|
direction == SwingConstants.SOUTH)) {
|
|
target.getCaret().setMagicCaretPosition(magicPosition);
|
|
}
|
|
} catch (BadLocationException ex) {
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
private int direction;
|
|
}
|
|
|
|
/*
|
|
* Position the caret to the beginning of the word.
|
|
* @see DefaultEditorKit#beginWordAction
|
|
* @see DefaultEditorKit#selectBeginWordAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class BeginWordAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
BeginWordAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
try {
|
|
int offs = target.getCaretPosition();
|
|
int begOffs = Utilities.getWordStart(target, offs);
|
|
if (select) {
|
|
target.moveCaretPosition(begOffs);
|
|
} else {
|
|
target.setCaretPosition(begOffs);
|
|
}
|
|
} catch (BadLocationException bl) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Position the caret to the end of the word.
|
|
* @see DefaultEditorKit#endWordAction
|
|
* @see DefaultEditorKit#selectEndWordAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class EndWordAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
EndWordAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
try {
|
|
int offs = target.getCaretPosition();
|
|
int endOffs = Utilities.getWordEnd(target, offs);
|
|
if (select) {
|
|
target.moveCaretPosition(endOffs);
|
|
} else {
|
|
target.setCaretPosition(endOffs);
|
|
}
|
|
} catch (BadLocationException bl) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Position the caret to the beginning of the previous word.
|
|
* @see DefaultEditorKit#previousWordAction
|
|
* @see DefaultEditorKit#selectPreviousWordAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class PreviousWordAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
PreviousWordAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
int offs = target.getCaretPosition();
|
|
boolean failed = false;
|
|
try {
|
|
Element curPara =
|
|
Utilities.getParagraphElement(target, offs);
|
|
offs = Utilities.getPreviousWord(target, offs);
|
|
if(offs < curPara.getStartOffset()) {
|
|
// we should first move to the end of the
|
|
// previous paragraph (bug #4278839)
|
|
offs = Utilities.getParagraphElement(target, offs).
|
|
getEndOffset() - 1;
|
|
}
|
|
} catch (BadLocationException bl) {
|
|
if (offs != 0) {
|
|
offs = 0;
|
|
}
|
|
else {
|
|
failed = true;
|
|
}
|
|
}
|
|
if (!failed) {
|
|
if (select) {
|
|
target.moveCaretPosition(offs);
|
|
} else {
|
|
target.setCaretPosition(offs);
|
|
}
|
|
}
|
|
else {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Position the caret to the next of the word.
|
|
* @see DefaultEditorKit#nextWordAction
|
|
* @see DefaultEditorKit#selectNextWordAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class NextWordAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
NextWordAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
int offs = target.getCaretPosition();
|
|
boolean failed = false;
|
|
int oldOffs = offs;
|
|
Element curPara =
|
|
Utilities.getParagraphElement(target, offs);
|
|
try {
|
|
offs = Utilities.getNextWord(target, offs);
|
|
if(offs >= curPara.getEndOffset() &&
|
|
oldOffs != curPara.getEndOffset() - 1) {
|
|
// we should first move to the end of current
|
|
// paragraph (bug #4278839)
|
|
offs = curPara.getEndOffset() - 1;
|
|
}
|
|
} catch (BadLocationException bl) {
|
|
int end = target.getDocument().getLength();
|
|
if (offs != end) {
|
|
if(oldOffs != curPara.getEndOffset() - 1) {
|
|
offs = curPara.getEndOffset() - 1;
|
|
} else {
|
|
offs = end;
|
|
}
|
|
}
|
|
else {
|
|
failed = true;
|
|
}
|
|
}
|
|
if (!failed) {
|
|
if (select) {
|
|
target.moveCaretPosition(offs);
|
|
} else {
|
|
target.setCaretPosition(offs);
|
|
}
|
|
}
|
|
else {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Position the caret to the beginning of the line.
|
|
* @see DefaultEditorKit#beginLineAction
|
|
* @see DefaultEditorKit#selectBeginLineAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class BeginLineAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
BeginLineAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
try {
|
|
int offs = target.getCaretPosition();
|
|
int begOffs = Utilities.getRowStart(target, offs);
|
|
if (select) {
|
|
target.moveCaretPosition(begOffs);
|
|
} else {
|
|
target.setCaretPosition(begOffs);
|
|
}
|
|
} catch (BadLocationException bl) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Position the caret to the end of the line.
|
|
* @see DefaultEditorKit#endLineAction
|
|
* @see DefaultEditorKit#selectEndLineAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class EndLineAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
EndLineAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
try {
|
|
int offs = target.getCaretPosition();
|
|
int endOffs = Utilities.getRowEnd(target, offs);
|
|
if (select) {
|
|
target.moveCaretPosition(endOffs);
|
|
} else {
|
|
target.setCaretPosition(endOffs);
|
|
}
|
|
} catch (BadLocationException bl) {
|
|
UIManager.getLookAndFeel().provideErrorFeedback(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Position the caret to the beginning of the paragraph.
|
|
* @see DefaultEditorKit#beginParagraphAction
|
|
* @see DefaultEditorKit#selectBeginParagraphAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class BeginParagraphAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
BeginParagraphAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
int offs = target.getCaretPosition();
|
|
Element elem = Utilities.getParagraphElement(target, offs);
|
|
offs = elem.getStartOffset();
|
|
if (select) {
|
|
target.moveCaretPosition(offs);
|
|
} else {
|
|
target.setCaretPosition(offs);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Position the caret to the end of the paragraph.
|
|
* @see DefaultEditorKit#endParagraphAction
|
|
* @see DefaultEditorKit#selectEndParagraphAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class EndParagraphAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
EndParagraphAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
int offs = target.getCaretPosition();
|
|
Element elem = Utilities.getParagraphElement(target, offs);
|
|
offs = Math.min(target.getDocument().getLength(),
|
|
elem.getEndOffset());
|
|
if (select) {
|
|
target.moveCaretPosition(offs);
|
|
} else {
|
|
target.setCaretPosition(offs);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Move the caret to the beginning of the document.
|
|
* @see DefaultEditorKit#beginAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class BeginAction extends TextAction {
|
|
|
|
/* Create this object with the appropriate identifier. */
|
|
BeginAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
if (select) {
|
|
target.moveCaretPosition(0);
|
|
} else {
|
|
target.setCaretPosition(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Move the caret to the end of the document.
|
|
* @see DefaultEditorKit#endAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class EndAction extends TextAction {
|
|
|
|
/* Create this object with the appropriate identifier. */
|
|
EndAction(String nm, boolean select) {
|
|
super(nm);
|
|
this.select = select;
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
Document doc = target.getDocument();
|
|
int dot = doc.getLength();
|
|
if (select) {
|
|
target.moveCaretPosition(dot);
|
|
} else {
|
|
target.setCaretPosition(dot);
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean select;
|
|
}
|
|
|
|
/*
|
|
* Select the word around the caret
|
|
* @see DefaultEditorKit#endAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class SelectWordAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
SelectWordAction() {
|
|
super(selectWordAction);
|
|
start = new BeginWordAction("pigdog", false);
|
|
end = new EndWordAction("pigdog", true);
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
start.actionPerformed(e);
|
|
end.actionPerformed(e);
|
|
}
|
|
|
|
private Action start;
|
|
private Action end;
|
|
}
|
|
|
|
/*
|
|
* Select the line around the caret
|
|
* @see DefaultEditorKit#endAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class SelectLineAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
SelectLineAction() {
|
|
super(selectLineAction);
|
|
start = new BeginLineAction("pigdog", false);
|
|
end = new EndLineAction("pigdog", true);
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
start.actionPerformed(e);
|
|
end.actionPerformed(e);
|
|
}
|
|
|
|
private Action start;
|
|
private Action end;
|
|
}
|
|
|
|
/*
|
|
* Select the paragraph around the caret
|
|
* @see DefaultEditorKit#endAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class SelectParagraphAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
SelectParagraphAction() {
|
|
super(selectParagraphAction);
|
|
start = new BeginParagraphAction("pigdog", false);
|
|
end = new EndParagraphAction("pigdog", true);
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
start.actionPerformed(e);
|
|
end.actionPerformed(e);
|
|
}
|
|
|
|
private Action start;
|
|
private Action end;
|
|
}
|
|
|
|
/*
|
|
* Select the entire document
|
|
* @see DefaultEditorKit#endAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class SelectAllAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
* @param nm the name of the action, Action.NAME.
|
|
* @param select whether to extend the selection when
|
|
* changing the caret position.
|
|
*/
|
|
SelectAllAction() {
|
|
super(selectAllAction);
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
Document doc = target.getDocument();
|
|
target.setCaretPosition(0);
|
|
target.moveCaretPosition(doc.getLength());
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* Remove the selection, if any.
|
|
* @see DefaultEditorKit#unselectAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class UnselectAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
*/
|
|
UnselectAction() {
|
|
super(unselectAction);
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
target.setCaretPosition(target.getCaretPosition());
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* Toggles the ComponentOrientation of the text component.
|
|
* @see DefaultEditorKit#toggleComponentOrientationAction
|
|
* @see DefaultEditorKit#getActions
|
|
*/
|
|
static class ToggleComponentOrientationAction extends TextAction {
|
|
|
|
/**
|
|
* Create this action with the appropriate identifier.
|
|
*/
|
|
ToggleComponentOrientationAction() {
|
|
super(toggleComponentOrientationAction);
|
|
}
|
|
|
|
/** The operation to perform when this action is triggered. */
|
|
public void actionPerformed(ActionEvent e) {
|
|
JTextComponent target = getTextComponent(e);
|
|
if (target != null) {
|
|
ComponentOrientation last = target.getComponentOrientation();
|
|
ComponentOrientation next;
|
|
if( last == ComponentOrientation.RIGHT_TO_LEFT )
|
|
next = ComponentOrientation.LEFT_TO_RIGHT;
|
|
else
|
|
next = ComponentOrientation.RIGHT_TO_LEFT;
|
|
target.setComponentOrientation(next);
|
|
target.repaint();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|