下面列出了javafx.scene.control.IndexRange#getStart ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Moves the caret to the position indicated by {@code pos}.
* Based on the selection policy, the selection is either <em>cleared</em>
* (i.e. anchor is set to the same position as caret), <em>adjusted</em>
* (i.e. anchor is not moved at all), or <em>extended</em>
* (i.e. {@code pos} becomes the new caret and, if {@code pos} points
* outside the current selection, the far end of the current selection
* becomes the anchor.
*/
default void moveTo(int pos, NavigationActions.SelectionPolicy selectionPolicy) {
switch(selectionPolicy) {
case CLEAR:
selectRange(pos, pos);
break;
case ADJUST:
selectRange(getAnchorPosition(), pos);
break;
case EXTEND:
IndexRange sel = getRange();
int anchor;
if(pos <= sel.getStart())
anchor = sel.getEnd();
else if(pos >= sel.getEnd())
anchor = sel.getStart();
else
anchor = getAnchorPosition();
selectRangeExpl(anchor, pos);
break;
}
}
/**
* If something is currently selected and the given position is outside of the selection, moves the selected
* rich-text document to the given position by deleting it from the area and re-inserting it at the given position.
* If nothing is selected, moves the caret ot that position.
*/
default void moveSelectedText(int position) {
IndexRange sel = getSelection();
if((position >= sel.getStart() && position <= sel.getEnd()) || sel.equals(GenericStyledArea.EMPTY_RANGE)) {
// no move, just position the caret
selectRange(position, position);
} else {
StyledDocument<PS, SEG, S> text = this.subDocument(sel.getStart(), sel.getEnd());
if(position > sel.getEnd())
position -= sel.getLength();
createMultiChange(2)
.deleteText(sel)
.insertAbsolutely(position, text)
.commit();
// select moved text
selectRange(position, position + text.length());
}
}
private void handleFirstPrimaryPress(MouseEvent e) {
// ensure focus
view.requestFocus();
CharacterHit hit = view.hit(e.getX(), e.getY());
view.clearTargetCaretOffset();
IndexRange selection = view.getSelection();
if(view.isEditable() &&
selection.getLength() != 0 &&
hit.getCharacterIndex().isPresent() &&
hit.getCharacterIndex().getAsInt() >= selection.getStart() &&
hit.getCharacterIndex().getAsInt() < selection.getEnd()) {
// press inside selection
dragSelection = DragState.POTENTIAL_DRAG;
dragNewSelection = DragState.NO_DRAG;
} else {
dragSelection = DragState.NO_DRAG;
dragNewSelection = DragState.NO_DRAG;
view.getOnOutsideSelectionMousePressed().handle(e);
}
}
private void duplicateLines(boolean up) {
IndexRange selRange = getSelectedLinesRange(true);
int selStart = selRange.getStart();
int selEnd = selRange.getEnd();
String selText = textArea.getText(selStart, selEnd);
if (!selText.endsWith("\n"))
selText += "\n";
replaceText(textArea, selStart, selStart, selText);
if (up)
selectRange(textArea, selStart, selStart + selText.length() - 1);
else {
int newSelStart = selStart + selText.length();
int newSelEnd = newSelStart + selText.length();
if (selText.endsWith("\n"))
newSelEnd--;
selectRange(textArea, newSelStart, newSelEnd);
}
}
/**
* Calculates the range of a value (background color, underline, etc.) that is shared between multiple
* consecutive {@link TextExt} nodes
*/
private void updateSharedShapeRange(T value, int start, int end, BiFunction<T, T, Boolean> equals) {
Runnable addNewValueRange = () -> ranges.add(Tuples.t(value, new IndexRange(start, end)));
if (ranges.isEmpty()) {
addNewValueRange.run();;
} else {
int lastIndex = ranges.size() - 1;
Tuple2<T, IndexRange> lastShapeValueRange = ranges.get(lastIndex);
T lastShapeValue = lastShapeValueRange._1;
// calculate smallest possible position which is consecutive to the given start position
final int prevEndNext = lastShapeValueRange.get2().getEnd();
if (start == prevEndNext && // Consecutive?
equals.apply(lastShapeValue, value)) { // Same style?
IndexRange lastRange = lastShapeValueRange._2;
IndexRange extendedRange = new IndexRange(lastRange.getStart(), end);
ranges.set(lastIndex, Tuples.t(lastShapeValue, extendedRange));
} else {
addNewValueRange.run();
}
}
}
@Override
public void moveTo(int pos, NavigationActions.SelectionPolicy selectionPolicy) {
switch(selectionPolicy) {
case CLEAR:
selectRangeExpl(pos, pos);
break;
case ADJUST:
selectRangeExpl(getAnchorPosition(), pos);
break;
case EXTEND:
IndexRange sel = getRange();
int anchor;
if (pos <= sel.getStart()) {
anchor = sel.getEnd();
} else if(pos >= sel.getEnd()) {
anchor = sel.getStart();
} else {
anchor = getAnchorPosition();
}
selectRangeExpl(anchor, pos);
break;
}
}
protected void addTextInFrontOfCurrentLine(String string) {
IndexRange range = mainArea.getSelection();
int first = range.getStart();
while (first > 0) {
if ("\n".equals(mainArea.getText(first - 1, first))) {
break;
}
first--;
}
mainArea.requestFocus();
mainArea.insertText(first, string);
}
@FXML
protected void addTextInFrontOfEachLine(String prefix) {
IndexRange range = mainArea.getSelection();
int start = range.getStart();
int end = range.getEnd();
addTextInFrontOfCurrentLine(prefix);
if (start == end) {
return;
}
int prefixLen = prefix.length();
start += prefixLen;
end += prefixLen;
int pos;
while (true) {
pos = mainArea.getText(start, end).indexOf('\n');
if (pos < 0) {
break;
}
mainArea.insertText(start + pos + 1, prefix);
start += pos + prefixLen + 1;
end += prefixLen;
int len = mainArea.getLength();
if (start >= end || start >= len || end >= len) {
break;
}
}
mainArea.requestFocus();
}
@FXML
protected void numberedList() {
IndexRange range = mainArea.getSelection();
int start = range.getStart();
int end = range.getEnd();
addTextInFrontOfCurrentLine("1. ");
if (start == end) {
return;
}
start += 3;
end += 3;
int pos;
int count = 1;
while (true) {
pos = mainArea.getText(start, end).indexOf('\n');
if (pos < 0) {
break;
}
count++;
mainArea.insertText(start + pos + 1, count + ". ");
int nlen = 2 + (count + "").length();
start += pos + 1 + nlen;
end += nlen;
int len = mainArea.getLength();
if (start >= end || start >= len || end >= len) {
break;
}
}
mainArea.requestFocus();
}
public static IndexRange textIndex(String hex, Charset charset,
IndexRange hexRange) {
int hIndex = 0, cindex = 0;
int cBegin = 0;
int cEnd = 0;
int hexBegin = hexRange.getStart();
int hexEnd = hexRange.getEnd();
if (hexBegin == 0 && hexEnd <= 0) {
return new IndexRange(0, 0);
}
boolean gotStart = false, gotEnd = false;
String[] lines = hex.split("\n");
StringBuilder text = new StringBuilder();
String lineText;
for (String lineHex : lines) {
lineText = new String(ByteTools.hexFormatToBytes(lineHex), charset);
lineText = lineText.replaceAll("\n", " ").replaceAll("\r", " ");
if (!gotStart && hexBegin >= hIndex && hexBegin <= (hIndex + lineHex.length())) {
cBegin = cindex + lineIndex(lineText, charset, hexBegin - hIndex);
gotStart = true;
}
if (hexEnd >= hIndex && hexEnd <= (hIndex + lineHex.length())) {
cEnd = cindex + lineIndex(lineText, charset, hexEnd - hIndex) + 1;
gotEnd = true;
break;
}
hIndex += lineHex.length() + 1;
cindex += lineText.length() + 1;
}
if (!gotStart) {
cBegin = text.length() - 1;
}
if (!gotEnd) {
cEnd = text.length();
}
if (cBegin > cEnd) {
cEnd = cBegin;
}
return new IndexRange(cBegin, cEnd);
}
public static int mapInt(int value, IndexRange originalRange, IndexRange newlRange) {
if (originalRange == null || newlRange == null || originalRange.getStart() > value || originalRange.getEnd() < value) {
return value;
}
int len = value - originalRange.getStart() + 1;
double ratio = newlRange.getLength() * 1.0 / originalRange.getLength();
return newlRange.getStart() + (int) Math.round(len * ratio);
}
private void backspacePressed(KeyEvent e) {
IndexRange selection = textArea.getSelection();
int start = selection.getStart();
int end = selection.getEnd();
if (selection.getLength() > 0) {
// selection is not empty --> delete selected text
deleteText(textArea, start, end);
} else {
// selection is empty
int startLine = offsetToLine(start);
int startLineOffset = lineToStartOffset(startLine);
if (start > startLineOffset && textArea.getText(startLineOffset, start).trim().isEmpty()) {
// selection is empty and caret is in leading whitespace of a line,
// but not at the beginning of a line --> unindent line
indentSelectedLines(false);
} else {
String line = textArea.getText(startLine);
int startLineEndOffset = startLineOffset + line.length();
Matcher matcher = (start == startLineEndOffset) ? AUTO_INDENT_PATTERN.matcher(line) : null;
if (matcher != null && matcher.matches() && matcher.group(2).isEmpty()) {
// caret is at end of line and line contains only whitespace characters
// and auto-indentable markers --> empty line
deleteText(textArea, startLineOffset, startLineEndOffset);
} else if (start > 0) {
// delete character before caret
deleteText(textArea, start - 1, start);
}
}
}
}
private IndentSelection rememberIndentSelection() {
IndentSelection isel = new IndentSelection();
IndexRange selection = textArea.getSelection();
int start = selection.getStart();
int end = selection.getEnd();
isel.startLine = offsetToLine(start);
isel.endLine = offsetToLine(end);
isel.startOffsetFromEnd = (start == end || start - lineToStartOffset(isel.startLine) > 0)
? lineToEndOffset(isel.startLine) - start
: -1; // beginning of line
isel.endOffsetFromEnd = lineToEndOffset(isel.endLine) - end;
return isel;
}
private void moveLinesDown(KeyEvent e) {
IndexRange selRange = getSelectedLinesRange(true);
int selStart = selRange.getStart();
int selEnd = selRange.getEnd();
if (selEnd == textArea.getLength())
return;
int after = offsetToLine(selEnd);
IndexRange afterRange = linesToRange(after, after, true);
int afterStart = afterRange.getStart();
int afterEnd = afterRange.getEnd();
String selText = textArea.getText(selStart, selEnd);
String afterText = textArea.getText(afterStart, afterEnd);
if (!afterText.endsWith("\n")) {
afterText += "\n";
if (selText.endsWith("\n"))
selText = selText.substring(0, selText.length() - 1);
}
// Note: using single textArea.replaceText() to avoid multiple changes in undo history
replaceText(textArea, selStart, afterEnd, afterText + selText);
int newSelStart = selStart + afterText.length();
int newSelEnd = newSelStart + selText.length();
selectRange(textArea, newSelStart, newSelEnd);
}
private void surroundSelectionAndReplaceMarker(String leading, String trailing, String hint,
DelimitedNode node, String newOpeningMarker, String newClosingMarker)
{
IndexRange selection = textArea.getSelection();
int start = selection.getStart();
int end = selection.getEnd();
String selectedText = textArea.getSelectedText();
// remove leading and trailing whitespaces from selected text
String trimmedSelectedText = selectedText.trim();
if (trimmedSelectedText.length() < selectedText.length()) {
start += selectedText.indexOf(trimmedSelectedText);
end = start + trimmedSelectedText.length();
}
BasedSequence openingMarker = node.getOpeningMarker();
BasedSequence closingMarker = node.getClosingMarker();
int selStart = start + leading.length() + (newOpeningMarker.length() - openingMarker.length());
int selEnd = selStart + trimmedSelectedText.length();
// insert hint text if selection is empty
if (hint != null && trimmedSelectedText.isEmpty()) {
trimmedSelectedText = hint;
selEnd = selStart + hint.length();
}
// replace text and update selection
// Note: using single textArea.replaceText() to avoid multiple changes in undo history
String before = textArea.getText(openingMarker.getEndOffset(), start);
String after = textArea.getText(end, closingMarker.getStartOffset());
replaceText(textArea, openingMarker.getStartOffset(), closingMarker.getEndOffset(),
newOpeningMarker + before + leading + trimmedSelectedText + trailing + after + newClosingMarker );
selectRange(textArea, selStart, selEnd);
}
/**
* Find single node that completely encloses the current selection and match a predicate.
*/
private <T extends Node> T findNodeAtSelection(FindNodePredicate predicate) {
IndexRange selection = textArea.getSelection();
int start = selection.getStart();
int end = selection.getEnd();
List<T> nodes = findNodes(start, end, predicate, false, false);
if (nodes.size() != 1)
return null;
T node = nodes.get(0);
BasedSequence text = (node instanceof DelimitedNode) ? ((DelimitedNode)node).getText() : node.getChars();
return (start >= text.getStartOffset() && end <= text.getEndOffset()) ? node : null;
}
/**
* Returns the line indices of the first and last line that are (partly) selected.
*/
private IndexRange getSelectedLines() {
IndexRange selection = textArea.getSelection();
int start = selection.getStart();
int end = Math.max(selection.getEnd() - 1, start); // excluding line separator
return new IndexRange(offsetToLine(start), offsetToLine(end));
}
CaretSelectionBindImpl(String caretName, String selectionName, GenericStyledArea<PS, SEG, S> area,
IndexRange startingRange) {
this(
(updater) -> new CaretNode(caretName, area, updater, startingRange.getStart()),
(updater) -> new SelectionImpl<>(selectionName, area, startingRange, updater)
);
}
private boolean isNodeSelected(Node node, IndexRange selection) {
return node.getStartOffset() <= selection.getEnd() && node.getEndOffset() > selection.getStart();
}
public void surroundSelection(String leading, String trailing, String hint, boolean selectWordIfEmpty) {
// Note: not using textArea.insertText() to insert leading and trailing
// because this would add two changes to undo history
IndexRange selection = textArea.getSelection();
int start = selection.getStart();
int end = selection.getEnd();
if (selectWordIfEmpty && start == end) {
// add letters or digits before selection
for (int i = start - 1; i >= 0; i--) {
if (!Character.isLetterOrDigit(textArea.getText(i, i + 1).charAt(0)))
break;
start--;
}
// add letters or digits after selection
int textLength = textArea.getLength();
for (int i = end; i < textLength; i++) {
if (!Character.isLetterOrDigit(textArea.getText(i, i + 1).charAt(0)))
break;
end++;
}
}
String selectedText = textArea.getText(start, end);
// remove leading and trailing whitespaces from selected text
String trimmedSelectedText = selectedText.trim();
if (trimmedSelectedText.length() < selectedText.length()) {
start += selectedText.indexOf(trimmedSelectedText);
end = start + trimmedSelectedText.length();
}
// remove leading whitespaces from leading text if selection starts at zero
if (start == 0)
leading = Utils.ltrim(leading);
// remove trailing whitespaces from trailing text if selection ends at text end
if (end == textArea.getLength())
trailing = Utils.rtrim(trailing);
// remove leading line separators from leading text
// if there are line separators before the selected text
if (leading.startsWith("\n")) {
for (int i = start - 1; i >= 0 && leading.startsWith("\n"); i--) {
if (!"\n".equals(textArea.getText(i, i + 1)))
break;
leading = leading.substring(1);
}
}
// remove trailing line separators from trailing or leading text
// if there are line separators after the selected text
boolean trailingIsEmpty = trailing.isEmpty();
String str = trailingIsEmpty ? leading : trailing;
if (str.endsWith("\n")) {
for (int i = end; i < textArea.getLength() && str.endsWith("\n"); i++) {
if (!"\n".equals(textArea.getText(i, i + 1)))
break;
str = str.substring(0, str.length() - 1);
}
if (trailingIsEmpty)
leading = str;
else
trailing = str;
}
int selStart = start + leading.length();
int selEnd = end + leading.length();
// insert hint text if selection is empty
if (hint != null && trimmedSelectedText.isEmpty()) {
trimmedSelectedText = hint;
selEnd = selStart + hint.length();
}
// replace text and update selection
replaceText(textArea, start, end, leading + trimmedSelectedText + trailing);
selectRange(textArea, selStart, selEnd);
}