下面列出了javax.swing.text.JTextComponent#getSelectionStart ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private boolean isExpectedNext(JTextComponent input, String nextChar)
{
String expected;
if (input.getSelectionStart() < input.getSelectionEnd())
{
try
{
expected = input.getText(input.getSelectionStart(), 1);
}
catch (BadLocationException ex)
{
log.warn("Could not get first character from input selection.", ex);
return false;
}
}
else
{
expected = "";
}
return nextChar.equalsIgnoreCase(expected);
}
@Override
public void actionPerformed(JTextComponent target, SyntaxDocument sDoc,
int dot, ActionEvent e) {
String indent = ActionUtils.getTab(target);
String[] lines = ActionUtils.getSelectedLines(target);
int start = target.getSelectionStart();
StringBuilder sb = new StringBuilder();
for (String line : lines) {
if (line.startsWith(indent)) {
sb.append(line.substring(indent.length()));
} else if (line.startsWith("\t")) {
sb.append(line.substring(1));
} else {
sb.append(line);
}
sb.append('\n');
}
target.replaceSelection(sb.toString());
target.select(start, start + sb.length());
}
@Override
protected boolean canFilter(JTextComponent component) {
final int newOffset = component.getSelectionStart();
final Document doc = component.getDocument();
if (newOffset > caretOffset && items != null && !items.isEmpty()) {
try {
String prefix = doc.getText(caretOffset, newOffset - caretOffset);
if (!isJavaIdentifierPart(prefix)) {
Completion.get().hideDocumentation();
Completion.get().hideCompletion();
}
} catch (BadLocationException ble) {
}
}
return false;
}
@Override
protected void preQueryUpdate(JTextComponent component) {
int newCaretOffset = component.getSelectionStart();
if (newCaretOffset >= caretOffset) {
try {
Document doc = component.getDocument();
Language language = getCompletableLanguage(doc, caretOffset);
if (isJavaIdentifierPart(language, doc.getText(caretOffset,
newCaretOffset - caretOffset))) {
return;
}
} catch (BadLocationException e) {
}
}
Completion.get().hideCompletion();
}
/**
* Return the lines that span the selection (split as an array of Strings)
* if there is no selection then current line is returned.
*
* Note that the strings returned will not contain the terminating line feeds.
*
* The text component will then have the full lines set as selection.
*
* @param target
* @return String[] of lines spanning selection / or Dot
*/
public static String[] getSelectedLines(JTextComponent target) {
String[] lines = null;
try {
PlainDocument document = (PlainDocument) target.getDocument();
int start = document.getParagraphElement(target.getSelectionStart()).getStartOffset();
int end;
if (target.getSelectionStart() == target.getSelectionEnd()) {
end = document.getParagraphElement(target.getSelectionEnd()).getEndOffset();
} else {
// if more than one line is selected, we need to subtract one from the end
// so that we do not select the line with the caret and no selection in it
end = document.getParagraphElement(target.getSelectionEnd() - 1).getEndOffset();
}
target.select(start, end);
lines = document.getText(start, end - start).split("\n");
target.select(start, end);
} catch (BadLocationException e) {
LOG.error(e.getMessage(), e);
lines = EMPTY_STRING_ARRAY;
}
return lines;
}
/**
* If the selection is multi lined, then the full lines are selected,
* otherwise, nothing is done.
* @param target
* @return true if the selection is multi-line, or a whole line
*/
public static boolean selectLines(JTextComponent target) {
if (target.getSelectionStart() == target.getSelectionEnd()) {
return false;
}
PlainDocument pDoc = (PlainDocument) target.getDocument();
Element es = pDoc.getParagraphElement(target.getSelectionStart());
// if more than one line is selected, we need to subtract one from the end
// so that we do not select the line with the caret and no selection in it
Element ee = pDoc.getParagraphElement(target.getSelectionEnd() - 1);
if (es.equals(ee) && ee.getEndOffset() != target.getSelectionEnd()) {
return false;
}
int start = es.getStartOffset();
int end = ee.getEndOffset();
target.select(start, end - 1);
return true;
}
/**
* Return the lines that span the selection (split as an array of Strings)
* if there is no selection then current line is returned.
*
* Note that the strings returned will not contain the terminating line feeds
* If the document is empty, then an empty string array is returned. So
* you can always iterate over the returned array without a null check
*
* The text component will then have the full lines set as selection
* @param target
* @return String[] of lines spanning selection / or line containing dot
*/
public static String[] getSelectedLines(JTextComponent target) {
String[] lines = null;
try {
PlainDocument pDoc = (PlainDocument) target.getDocument();
int start = pDoc.getParagraphElement(target.getSelectionStart()).getStartOffset();
int end;
if (target.getSelectionStart() == target.getSelectionEnd()) {
end = pDoc.getParagraphElement(target.getSelectionEnd()).getEndOffset();
} else {
// if more than one line is selected, we need to subtract one from the end
// so that we do not select the line with the caret and no selection in it
end = pDoc.getParagraphElement(target.getSelectionEnd() - 1).getEndOffset();
}
target.select(start, end);
lines = pDoc.getText(start, end - start).split("\n");
target.select(start, end);
} catch (BadLocationException ex) {
Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, null, ex);
lines = EMPTY_STRING_ARRAY;
}
return lines;
}
/**
* {@inheritDoc}
* @param e
*/
@Override
public void actionPerformed(JTextComponent target, SyntaxDocument sDoc,
int dot, ActionEvent e) {
if (lineCommentPattern == null) {
lineCommentPattern = Pattern.compile("(^" + lineCommentStart + ")(.*)");
}
String[] lines = ActionUtils.getSelectedLines(target);
int start = target.getSelectionStart();
StringBuffer toggled = new StringBuffer();
for (int i = 0; i < lines.length; i++) {
Matcher m = lineCommentPattern.matcher(lines[i]);
if (m.find()) {
toggled.append(m.replaceFirst("$2"));
} else {
toggled.append(lineCommentStart);
toggled.append(lines[i]);
}
toggled.append('\n');
}
target.replaceSelection(toggled.toString());
target.select(start, start + toggled.length());
}
public void actionPerformed(ActionEvent e) {
JTextComponent target = getTextComponent(e);
Integer tabStop = (Integer) target.getDocument().getProperty(PlainDocument.tabSizeAttribute);
String indent = ActionUtils.SPACES.substring(0, tabStop);
if (target != null) {
String[] lines = ActionUtils.getSelectedLines(target);
int start = target.getSelectionStart();
StringBuilder sb = new StringBuilder();
for (String line : lines) {
if (line.startsWith(indent)) {
sb.append(line.substring(indent.length()));
} else if (line.startsWith("\t")) {
sb.append(line.substring(1));
} else {
sb.append(line);
}
sb.append('\n');
}
target.replaceSelection(sb.toString());
target.select(start, start + sb.length());
}
}
private static void replaceTextInTextComponentEnsuringSelection(@Nonnull String textToSet, JTextComponent component) {
String existingText = component.getText();
if (!existingText.equals(textToSet)) {
component.setText(textToSet);
// textToSet should be selected even if we have no selection before (if we have the selection then setText will remain it)
if (component.getSelectionStart() == component.getSelectionEnd()) component.selectAll();
}
}
@Override
public void adjust() {
boolean enable = false;
Component comp = getFocusOwner();
if (comp instanceof JTextComponent && comp.isEnabled()) {
JTextComponent textComp = (JTextComponent) comp;
enable = textComp.getSelectionEnd() - textComp.getSelectionStart() != textComp.getDocument().getLength();
} else {
SelectAllCapable selectable = getTarget(SelectAllCapable.class);
if (selectable != null) {
enable = selectable.canSelectAll();
}
}
setEnabled(enable);
}
/** Get the selection if there's any or get the identifier around
* the position if there's no selection.
* @param c component to work with
* @param offset position in document - usually the caret.getDot()
* @return the block (starting and ending position) enclosing the identifier
* or null if no identifier was found
*/
public static int[] getSelectionOrIdentifierBlock(JTextComponent c, int offset)
throws BadLocationException {
Document doc = c.getDocument();
Caret caret = c.getCaret();
int[] ret;
if (Utilities.isSelectionShowing(caret)) {
ret = new int[] { c.getSelectionStart(), c.getSelectionEnd() };
} else if (doc instanceof BaseDocument){
ret = getIdentifierBlock((BaseDocument)doc, offset);
} else {
ret = getIdentifierBlock(c, offset);
}
return ret;
}
final int getAnchorOffset() {
int offset = anchorOffset;
if (offset == -1) {
// Get caret position
JTextComponent editorComponent = getEditorComponent();
if (editorComponent != null) {
offset = editorComponent.getSelectionStart();
}
}
return offset;
}
@Override
public CompletionTask createTask(int queryType, JTextComponent component) {
if (queryType != CompletionProvider.COMPLETION_QUERY_TYPE && queryType !=CompletionProvider.COMPLETION_ALL_QUERY_TYPE) {
return null;
}
return new AsyncCompletionTask(new BeansCompletionQuery(queryType, component, component.getSelectionStart(), true), component);
}
private GsfCodeTemplateFilter(JTextComponent component, int offset) {
this.startOffset = offset;
this.endOffset = component.getSelectionStart() == offset ? component.getSelectionEnd() : -1;
Document doc = component.getDocument();
CodeCompletionHandler completer = doc == null ? null : GsfCompletionProvider.getCompletable(doc, startOffset);
if (completer != null) {
templates = completer.getApplicableTemplates(doc, startOffset, endOffset);
}
}
/**
* Expand the string template and replaces the selection with the expansion
* of the template. The template String may contain any of the following
* special tags.
*
* <li>{@code #{selection}} replaced with the selection, if any. If there is
* no selection, then the {@code #{selection}} tag will be removed.
* <li>{@code #{p:any text}} will be replaced by {@code any text} and then
* set selection to {@code any text}
*
* This method properly handles indentation as follows:
* The indentation of the whole block will match the indentation of the caret
* line, or the line with the beginning of the selection, if the selection is
* in whole line, i.e.e one or more lines of selected text. {@see selectLines()}
*
* @param target JEditorCOmponent to be affected
* @param templateLines template split as a String array of lines.
*
* @see insertLinesTemplate
*/
public static void insertLinesTemplate(JTextComponent target, String[] templateLines) {
// get some stuff we'll need:
String thisIndent = getIndent(getLineAt(target, target.getSelectionStart()));
String[] selLines = getSelectedLines(target);
int selStart = -1, selEnd = -1;
StringBuffer sb = new StringBuffer();
for (String tLine : templateLines) {
int selNdx = tLine.indexOf("#{selection}");
if (selNdx >= 0) {
// for each of the selected lines:
for (String selLine : selLines) {
sb.append(tLine.subSequence(0, selNdx));
sb.append(selLine);
sb.append('\n');
}
} else {
sb.append(thisIndent);
// now check for any ptags
Matcher pm = PTAGS_PATTERN.matcher(tLine);
int lineStart = sb.length();
while (pm.find()) {
selStart = pm.start() + lineStart;
pm.appendReplacement(sb, pm.group(1));
selEnd = sb.length();
}
pm.appendTail(sb);
sb.append('\n');
}
}
int ofst = target.getSelectionStart();
target.replaceSelection(sb.toString());
if (selStart >= 0) {
// target.setCaretPosition(selStart);
target.select(ofst + selStart, ofst + selEnd);
}
}
@Override
public void keyTyped(KeyEvent e)
{
if (!hiscoreConfig.autocomplete())
{
return;
}
final JTextComponent input = (JTextComponent)e.getSource();
final String inputText = input.getText();
// Only autocomplete if the selection end is at the end of the text.
if (input.getSelectionEnd() != inputText.length())
{
return;
}
// Character to be inserted at the selection start.
final String charToInsert = Character.toString(e.getKeyChar());
// Don't attempt to autocomplete if the name is invalid.
// This condition is also true when the user presses a key like backspace.
if (INVALID_CHARS.matcher(charToInsert).find()
|| INVALID_CHARS.matcher(inputText).find())
{
return;
}
// Check if we are already autocompleting.
if (autocompleteName != null && autocompleteNamePattern.matcher(inputText).matches())
{
if (isExpectedNext(input, charToInsert))
{
try
{
// Insert the character and move the selection.
final int insertIndex = input.getSelectionStart();
Document doc = input.getDocument();
doc.remove(insertIndex, 1);
doc.insertString(insertIndex, charToInsert, null);
input.select(insertIndex + 1, input.getSelectionEnd());
}
catch (BadLocationException ex)
{
log.warn("Could not insert character.", ex);
}
// Prevent default behavior.
e.consume();
}
else // Character to insert does not match current autocompletion. Look for another name.
{
newAutocomplete(e);
}
}
else // Search for a name to autocomplete
{
newAutocomplete(e);
}
}
boolean replaceImpl(Map<String, Object> props, boolean oppositeDir, JTextComponent c) throws BadLocationException {
props = getValidFindProperties(props);
boolean back = Boolean.TRUE.equals(props.get(FIND_BACKWARD_SEARCH));
if (oppositeDir) {
back = !back;
}
boolean blockSearch = Boolean.TRUE.equals(props.get(FIND_BLOCK_SEARCH));
Position blockSearchStartPos = (Position) props.get(FIND_BLOCK_SEARCH_START);
int blockSearchStartOffset = (blockSearchStartPos != null) ? blockSearchStartPos.getOffset() : -1;
if (c != null) {
String s = (String)props.get(FIND_REPLACE_WITH);
Caret caret = c.getCaret();
if (caret.isSelectionVisible() && caret.getDot() != caret.getMark()){
Object dp = props.get(FIND_BACKWARD_SEARCH);
boolean direction = (dp != null) ? ((Boolean)dp).booleanValue() : false;
int dotPos = (oppositeDir ^ direction ? c.getSelectionEnd() : c.getSelectionStart());
c.setCaretPosition(dotPos);
}
FindReplaceResult result = findReplaceImpl(s, props, oppositeDir, c);
if (result!=null){
s = result.getReplacedString();
} else {
return false;
}
Document doc = c.getDocument();
int startOffset = c.getSelectionStart();
int len = c.getSelectionEnd() - startOffset;
DocUtils.atomicLock(doc);
try {
if (len > 0) {
doc.remove(startOffset, len);
}
if (s != null && s.length() > 0) {
try {
NavigationHistory.getEdits().markWaypoint(c, startOffset, false, true);
} catch (BadLocationException e) {
LOG.log(Level.WARNING, "Can't add position to the history of edits.", e); //NOI18N
}
doc.insertString(startOffset, s, null);
if (startOffset == blockSearchStartOffset) { // Replaced at begining of block
blockSearchStartPos = doc.createPosition(startOffset);
props.put(EditorFindSupport.FIND_BLOCK_SEARCH_START, blockSearchStartPos);
}
}
} finally {
DocUtils.atomicUnlock(doc);
if (blockSearch){
setBlockSearchHighlight(blockSearchStartOffset, getBlockEndOffset());
}
}
// adjust caret pos after replace operation
int adjustedCaretPos = (back || s == null) ? startOffset : startOffset + s.length();
caret.setDot(adjustedCaretPos);
}
return true;
}
@Override
public boolean accepts(JTextComponent jtc) {
int i1 = jtc.getSelectionStart();
int i2 = jtc.getSelectionEnd();
return i1 != i2;
}
@Override
public void show(Component invoker, int x, int y) {
JTextComponent target = getTextComponent(invoker);
if (target == null) {
return;
}
if (target instanceof JPasswordField) {
boolean enabled = false;
Object copyClientProp = target.getClientProperty("JPasswordField.cutCopyAllowed");
if (copyClientProp != null && copyClientProp instanceof Boolean && (Boolean) copyClientProp == true) {
enabled = true;
}
this.copyMenuItem.setEnabled(enabled);
this.cutMenuItem.setEnabled(enabled);
} else {
if (target.getSelectionStart() != target.getSelectionEnd()) {
this.copyMenuItem.setEnabled(true);
} else {
this.copyMenuItem.setEnabled(false);
}
if (target.getSelectionStart() != target.getSelectionEnd() && target.isEditable()) {
this.cutMenuItem.setEnabled(true);
} else {
this.cutMenuItem.setEnabled(false);
}
}
if (target.isEditable()) {
this.pasteMenuItem.setEnabled(true);
} else {
this.pasteMenuItem.setEnabled(false);
}
if (target.isEditable() && target.getSelectionStart() != target.getSelectionEnd()) {
this.deleteMenuItem.setEnabled(true);
} else {
this.deleteMenuItem.setEnabled(false);
}
if (getTextLength(target) > 0) {
this.selectAllMenuItem.setEnabled(true);
} else {
this.selectAllMenuItem.setEnabled(false);
}
// if ((getTextLength(target) > 0) && target.isEditable()) {
// this.clearMenuItem.setEnabled(true);
// } else {
// this.clearMenuItem.setEnabled(false);
// }
super.show(invoker, x, y);
this.parent.requestFocus();
}