下面列出了怎么用javax.swing.text.Position的API类实例代码及写法,或者点击链接到github查看源代码。
static int viewToModel(JTextComponent tc, double x, double y, Position.Bias[] biasReturn) {
int offs = -1;
Document doc = tc.getDocument();
if (doc instanceof AbstractDocument) {
((AbstractDocument)doc).readLock();
}
try {
Rectangle alloc = getVisibleEditorRect(tc);
if (alloc != null) {
View rootView = tc.getUI().getRootView(tc);
View documentView = rootView.getView(0);
if (documentView instanceof EditorView) {
documentView.setSize(alloc.width, alloc.height);
offs = ((EditorView) documentView).viewToModelChecked(x, y, alloc, biasReturn);
} else {
rootView.setSize(alloc.width, alloc.height);
offs = rootView.viewToModel((float) x, (float) y, alloc, biasReturn);
}
}
} finally {
if (doc instanceof AbstractDocument) {
((AbstractDocument)doc).readUnlock();
}
}
return offs;
}
/**
* Return union of this region with the given region.
* <br>
* If the given region is empty then return "this" region.
*
* @param region region to union with.
* @param ignoreEmpty if false and "this" region is empty (or region.isEmpty())
* then the returned region will "include" bounds of the empty region.
* @return new region instance which is union of the given bounds
*/
public OffsetRegion union(OffsetRegion region, boolean ignoreEmpty) {
int thisStartOffset = this.startOffset();
int thisEndOffset = this.endOffset();
if (ignoreEmpty) {
if (region.isEmpty()) {
return this;
}
if (thisStartOffset == thisEndOffset) {
return region;
}
}
if (region.startOffset() >= thisStartOffset) {
if (region.endOffset() <= thisEndOffset) {
return this; // Included
} else { // endOffset > this.endOffset
return new OffsetRegion(this.startPos, region.endPos);
}
} else { // startOffset < this.startOffset
Position endP = (region.endOffset() > thisEndOffset) ? region.endPos : this.endPos;
return new OffsetRegion(region.startPos, endP);
}
}
public synchronized void write(char[] cbuf, int off, int len,
int[] saveOffsets, Position.Bias[] saveBiases) throws IOException {
if (simple) {
underWriter.write(cbuf, off, len);
return;
}
if (saveOffsets != null) {
ftps.addSaveSet(bufferSize, len, saveOffsets, saveBiases);
}
lastFlush = false; // signal write() was the last so flush() can be done
if (debug) {
System.err.println("FormatWriter.write(): '" // NOI18N
+ org.netbeans.editor.EditorDebug.debugChars(cbuf, off, len)
+ "', length=" + len + ", bufferSize=" + bufferSize); // NOI18N
}
// Add the chars to the buffer for formatting
addToBuffer(cbuf, off, len);
}
public void testRemoveAligned2Clip() {
PositionsBag hs = new PositionsBag(doc);
SimpleAttributeSet attribsA = new SimpleAttributeSet();
attribsA.addAttribute("set-name", "attribsA");
hs.addHighlight(pos(10), pos(40), attribsA);
hs.removeHighlights(pos(10), pos(20), true);
GapList<Position> marks = hs.getMarks();
GapList<AttributeSet> atttributes = hs.getAttributes();
assertEquals("Wrong number of highlights", 2, marks.size());
assertEquals("1. highlight - wrong start offset", 20, marks.get(0).getOffset());
assertEquals("1. highlight - wrong end offset", 40, marks.get(1).getOffset());
assertEquals("1. highlight - wrong attribs", "attribsA", atttributes.get(0).getAttribute("set-name"));
assertNull(" 1. highlight - wrong end", atttributes.get(1));
hs.removeHighlights(pos(30), pos(40), true);
assertEquals("Wrong number of highlights", 2, marks.size());
assertEquals("1. highlight - wrong start offset", 20, marks.get(0).getOffset());
assertEquals("1. highlight - wrong end offset", 30, marks.get(1).getOffset());
assertEquals("1. highlight - wrong attribs", "attribsA", atttributes.get(0).getAttribute("set-name"));
assertNull(" 1. highlight - wrong end", atttributes.get(1));
}
/** Add the save-set to the registry and perform the checking
* whether the offsets are OK.
*/
synchronized void addSaveSet(int baseOffset, int writtenLen,
int[] offsets, Position.Bias[] biases) {
// Check whether the offsets are OK
for (int i = 0; i < offsets.length; i++) {
if (offsets[i] < 0 || offsets[i] > writtenLen) {
throw new IllegalArgumentException(
"Invalid save-offset=" + offsets[i] + " at index=" + i // NOI18N
+ ". Written length is " + writtenLen); // NOI18N
}
}
SaveSet newSet = new SaveSet(baseOffset, offsets, biases);
if (firstSet != null) {
lastSet.next = newSet;
lastSet = newSet;
} else { // first set
firstSet = lastSet = newSet;
}
}
@Override
public int indentLine(Document doc, int offset) {
Indent indent = Indent.get(doc);
indent.lock();
try {
if (doc instanceof BaseDocument) {
((BaseDocument) doc).atomicLock();
}
try {
Position pos = doc.createPosition(offset);
indent.reindent(offset);
return pos.getOffset();
} catch (BadLocationException ble) {
return offset;
} finally {
if (doc instanceof BaseDocument) {
((BaseDocument) doc).atomicUnlock();
}
}
} finally {
indent.unlock();
}
}
public static PositionBounds linePart(FileObject file, int start, int end) {
try {
DataObject od = DataObject.find(file);
if (od == null)
return null;
EditorCookie ec = od.getCookie(EditorCookie.class);
if (!(ec instanceof CloneableEditorSupport)) {
return null;
}
final CloneableEditorSupport ces = (CloneableEditorSupport) ec;
checkOffsetsAndLog(start, end);
return new PositionBounds(ces.createPositionRef(start, Position.Bias.Forward), ces.createPositionRef(end, Position.Bias.Backward));
} catch (IOException e) {
LOG.log(Level.INFO, null, e);
return null;
}
}
public void testBackwardBiasPositions() throws Exception {
RandomTestContainer container = createContainer();
RandomTestContainer.Context context = container.context();
DocumentContentTesting.insert(context, 0, "ahoj cau");
Position bbPos1 = DocumentContentTesting.createPosition(context, 1, true);
// Position pos2 = DocumentContentTesting.createPosition(context, 2);
Position bbPos3 = DocumentContentTesting.createPosition(context, 3, true);
DocumentContentTesting.insert(context, 3, "test");
container.runChecks(context);
DocumentContentTesting.remove(context, 0, 4);
container.runChecks(context);
DocumentContentTesting.undo(context, 1); // checkContent() automatic
DocumentContentTesting.undo(context, 1); // checkContent() automatic
DocumentContentTesting.redo(context, 1); // checkContent() automatic
DocumentContentTesting.redo(context, 1); // checkContent() automatic
container.runChecks(context);
}
private static Position getPosition(final StyledDocument doc, final int offset) {
class Impl implements Runnable {
private Position pos;
public void run() {
if (offset < 0 || offset >= doc.getLength())
return ;
try {
pos = doc.createPosition(offset - NbDocument.findLineColumn(doc, offset));
} catch (BadLocationException ex) {
//should not happen?
Logger.getLogger(ComputeAnnotations.class.getName()).log(Level.FINE, null, ex);
}
}
}
Impl i = new Impl();
doc.render(i);
return i.pos;
}
@Override
public Shape modelToViewChecked(int offset, Shape alloc, Position.Bias bias) {
int startOffset = getStartOffset();
Rectangle2D.Double mutableBounds = ViewUtils.shape2Bounds(alloc);
int charIndex = offset - startOffset;
if (charIndex == 1) {
mutableBounds.x += firstTabWidth;
} else if (charIndex > 1) {
int extraTabCount = getLength() - 1;
if (extraTabCount > 0) {
mutableBounds.x += firstTabWidth + (charIndex - 1) * ((width - firstTabWidth) / extraTabCount);
}
}
mutableBounds.width = 1;
return mutableBounds;
}
private int [] addHighlightImpl(Position startPosition, Position endPosition, AttributeSet attributes) {
if (startPosition.getOffset() == endPosition.getOffset()) {
return null;
} else {
assert startPosition.getOffset() < endPosition.getOffset() :
"Start position must be before the end position."; //NOI18N
assert attributes != null : "Highlight attributes must not be null."; //NOI18N
}
if (mergeHighlights) {
merge(startPosition, endPosition, attributes);
} else {
trim(startPosition, endPosition, attributes);
}
return new int [] { startPosition.getOffset(), endPosition.getOffset() };
}
protected void substituteText(JTextComponent c, int offset, int len, String toAdd) {
BaseDocument doc = (BaseDocument) c.getDocument();
CharSequence prefix = getInsertPrefix();
String text = prefix.toString();
if (toAdd != null) {
text += toAdd;
}
doc.atomicLock();
try {
Position position = doc.createPosition(offset);
doc.remove(offset, len);
doc.insertString(position.getOffset(), text.toString(), null);
} catch (BadLocationException ble) {
// nothing can be done to update
} finally {
doc.atomicUnlock();
}
}
public PositionBounds getPosition() {
try {
DataObject dobj = DataObject.find(getParentFile());
if (dobj != null) {
EditorCookie.Observable obs = (EditorCookie.Observable)dobj.getCookie(EditorCookie.Observable.class);
if (obs != null && obs instanceof CloneableEditorSupport) {
CloneableEditorSupport supp = (CloneableEditorSupport)obs;
if (loc == null) {
loc = location();
}
PositionBounds bounds = new PositionBounds(
supp.createPositionRef(loc[0], Position.Bias.Forward),
supp.createPositionRef(Math.max(loc[0], loc[1]), Position.Bias.Forward)
);
return bounds;
}
}
} catch (DataObjectNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
/**
* Notification from invalidator thread, the grammar need to be reloaded.
*/
public synchronized void invalidateGrammar() {
// make current loader a zombie
if (state == VALID) {
String msg = NbBundle.getMessage(GrammarManager.class, "MSG_loading_cancel");
StatusDisplayer.getDefault().setStatusText(msg);
}
doc.removeDocumentListener(this);
//remove FileChangeListeners from the external DTD files
for(FileObject fo : externalDTDs) {
// System.out.println("[GrammarManager] removed FileObjectListener from " + fo.getPath());
fo.removeFileChangeListener(this);
}
externalDTDs.clear();
guarded = new Position[0];
state = INVALID;
}
public boolean reject(Object o) {
return (o == fold.getType())
|| (o == fold.getDescription()) // requires non-null description during construction
|| (o == fold.getParent())
|| (o instanceof FoldOperationImpl)
|| (o instanceof Position);
// Will count possible FoldChildren and ExtraInfo
}
public void testSimpleUndo() throws Exception {
RandomTestContainer container = createContainer();
RandomTestContainer.Context context = container.context();
DocumentContentTesting.insert(context, 0, "ahoj cau");
Position pos4 = DocumentContentTesting.createPosition(context, 4);
DocumentContentTesting.remove(context, 3, 4);
container.runChecks(context);
DocumentContentTesting.undo(context, 1);
container.runChecks(context);
assertEquals(pos4.getOffset(), 4);
}
/**
* Invokes the <code>getNextVisualPositionFrom</code> method on each UI handled by this object.
*
* @return the value obtained from the first UI, which is
* the UI obtained from the default <code>LookAndFeel</code>
*/
public int getNextVisualPositionFrom(JTextComponent a, int b, Position.Bias c, int d, Position.Bias[] e)
throws BadLocationException {
int returnValue =
((TextUI) (uis.elementAt(0))).getNextVisualPositionFrom(a,b,c,d,e);
for (int i = 1; i < uis.size(); i++) {
((TextUI) (uis.elementAt(i))).getNextVisualPositionFrom(a,b,c,d,e);
}
return returnValue;
}
/**
* Sets navigation filter for a certain operation type, defined by {@link MoveCaretsOrigin}.
* <p>
* The registered filter will receive <b>only those caret movements</b>, which correspond to the
* passed {@link MoveCaretsOrigin}. To receive all caret movements, register for {@link MoveCaretsOrigin#DEFAULT}
* or use {@link JTextComponent#setNavigationFilter}.
* </p><p>
* All the key part(s) of MoveCaretOrigin of a caret operation and `origin' parameter in this function must
* match in order for the filter to be invoked.
* </p><p>
* The NavigationFilter implementation <b>may downcast</b> the passed {@link NavigationFilter.FilterBypass FilterBypass}
* parameter to {@link NavigationFilterBypass} to get full infomration about the movement.
* </p>
* @param component the component which will use the filter
* @param origin the origin
* @param naviFilter the installed filter
* @see JTextComponent#setNavigationFilter
* @see NavigationFilterBypass
* @since 2.10
*/
public static void setNavigationFilter(JTextComponent component, MoveCaretsOrigin origin, @NullAllowed NavigationFilter naviFilter) {
if (origin == null) {
origin = MoveCaretsOrigin.DEFAULT;
}
final NavigationFilter prev = getNavigationFilter(component, origin);
if (naviFilter != null) {
// Note:
// if the caller passes in a non-cascading filter, we would loose the filter chain information.
// the alien filter is wrapped by CascadingNavigationFilter delegator, so the previous filter
// link is preserved.
if (!(naviFilter instanceof CascadingNavigationFilter)) {
final NavigationFilter del = naviFilter;
naviFilter = new CascadingNavigationFilter() {
@Override
public void setDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {
del.setDot(fb, dot, bias);
}
@Override
public void moveDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {
del.moveDot(fb, dot, bias);
}
@Override
public int getNextVisualPositionFrom(JTextComponent text, int pos, Position.Bias bias, int direction, Position.Bias[] biasRet) throws BadLocationException {
return del.getNextVisualPositionFrom(text, pos, bias, direction, biasRet);
}
};
}
((CascadingNavigationFilter)naviFilter).setOwnerAndPrevious(component, origin, prev);
}
if (MoveCaretsOrigin.DEFAULT == origin) {
component.setNavigationFilter(naviFilter);
} else {
doPutNavigationFilter(component, origin.getActionType(), prev);
}
}
private String dumpHighlight(Position start, Position end, AttributeSet attribs) {
StringBuilder sb = new StringBuilder();
sb.append("<");
sb.append(start == null ? " " : start.getOffset());
sb.append(",");
sb.append(end == null ? " " : end.getOffset());
sb.append(",");
dumpAttributes(sb, attribs);
sb.append(">");
return sb.toString();
}
/**
* Invokes the <code>modelToView</code> method on each UI handled by this object.
*
* @return the value obtained from the first UI, which is
* the UI obtained from the default <code>LookAndFeel</code>
*/
public Rectangle modelToView(JTextComponent a, int b, Position.Bias c)
throws BadLocationException {
Rectangle returnValue =
((TextUI) (uis.elementAt(0))).modelToView(a,b,c);
for (int i = 1; i < uis.size(); i++) {
((TextUI) (uis.elementAt(i))).modelToView(a,b,c);
}
return returnValue;
}
@Override
public Shape modelToViewChecked(int offset, Shape alloc, Position.Bias bias) {
// TextLayout textLayout = getTextLayout();
// if (textLayout == null) {
// return alloc; // Leave given bounds
// }
// Rectangle2D.Double bounds = ViewUtils.shape2Bounds(alloc);
// return bounds;
return alloc;
}
/**
* Returns the next list element whose {@code toString} value
* starts with the given prefix.
*
* @param prefix the string to test for a match
* @param startIndex the index for starting the search
* @param bias the search direction, either
* Position.Bias.Forward or Position.Bias.Backward.
* @return the index of the next list element that
* starts with the prefix; otherwise {@code -1}
* @exception IllegalArgumentException if prefix is {@code null}
* or startIndex is out of bounds
* @since 1.4
*/
public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
ListModel<E> model = getModel();
int max = model.getSize();
if (prefix == null) {
throw new IllegalArgumentException();
}
if (startIndex < 0 || startIndex >= max) {
throw new IllegalArgumentException();
}
prefix = prefix.toUpperCase();
// start search from the next element after the selected element
int increment = (bias == Position.Bias.Forward) ? 1 : -1;
int index = startIndex;
do {
E element = model.getElementAt(index);
if (element != null) {
String string;
if (element instanceof String) {
string = ((String)element).toUpperCase();
}
else {
string = element.toString();
if (string != null) {
string = string.toUpperCase();
}
}
if (string != null && string.startsWith(prefix)) {
return index;
}
}
index = (index + increment + max) % max;
} while (index != startIndex);
return -1;
}
public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
lock();
try {
if (view != null) {
return view.modelToView(pos, a, b);
}
return null;
} finally {
unlock();
}
}
public boolean contains(Position pos, boolean allowHoles) {
if (!allowHoles) {
return header.getBegin().getOffset() <= pos.getOffset() &&
footer.getEnd().getOffset() >= pos.getOffset();
} else {
if (header.getBegin().getOffset() <= pos.getOffset() &&
header.getEnd().getOffset() >= pos.getOffset()) {
return true;
}
return footer.getBegin().getOffset() <= pos.getOffset() &&
footer.getEnd().getOffset() >= pos.getOffset();
}
}
private static int writeString(BaseDocument doc, String text, int offset){
int formatLength = 0;
Indent indenter = Indent.get(doc);
Reformat formatter = Reformat.get(doc);
indenter.lock();
formatter.lock();
try {
doc.atomicLock();
try{
offset = indenter.indentNewLine(offset + 1);
doc.insertString(offset, text, null );
Position endPos = doc.createPosition(offset + text.length() - 1);
formatter.reformat(offset, endPos.getOffset());
formatLength = Math.max(0, endPos.getOffset() - offset);
}
catch(BadLocationException ex){
Exceptions.printStackTrace(ex);
}
finally {
doc.atomicUnlock();
}
} finally {
formatter.unlock();
indenter.unlock();
}
return offset + formatLength + 1;
}
static void handleIdentifier(Document doc, List<Position[]> p, int[] span, String name) {
if (span == null)
return ;
List<int[]> spans = new LinkedList<int[]>();
List<String> separatedWords = separateWords(name, spans);
for (int[] s : spans) {
try {
p.add(new Position[]{doc.createPosition(span[0] + s[0]), doc.createPosition(span[0] + s[1])});
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
}
}
}
/**
* Invokes the <code>viewToModel</code> method on each UI handled by this object.
*
* @return the value obtained from the first UI, which is
* the UI obtained from the default <code>LookAndFeel</code>
*/
public int viewToModel(JTextComponent a, Point b, Position.Bias[] c) {
int returnValue =
((TextUI) (uis.elementAt(0))).viewToModel(a,b,c);
for (int i = 1; i < uis.size(); i++) {
((TextUI) (uis.elementAt(i))).viewToModel(a,b,c);
}
return returnValue;
}
/** Get the previous position of the position given by parameters.
* It can be either just offset decreasing but it can be movement
* to the previous token for the token boundary.
* @return next token-position or null for the first position in the chain
*/
public FormatTokenPosition getPreviousPosition(TokenItem token, int offset,
Position.Bias bias) {
FormatTokenPosition ret = null;
if (token == null) { // end of chain
TokenItem lastToken = findNonEmptyToken(getLastToken(), true);
if (lastToken != null) { // regular last token
ret = getPosition(lastToken, lastToken.getImage().length() - 1,
Position.Bias.Forward);
}
} else { // regular token
offset--;
if (offset < 0) {
token = token.getPrevious();
if (token != null) { // was first pos in first token
ret = getPosition(token, token.getImage().length() - 1,
Position.Bias.Forward);
}
} else { // still inside token
ret = getPosition(token, offset,
Position.Bias.Forward);
}
}
return ret;
}
@Override
public Rectangle2D modelToView2D(JTextComponent a, int b, Position.Bias c) throws BadLocationException {
Rectangle2D returnValue =
((TextUI) (uis.elementAt(0))).modelToView2D(a,b,c);
for (int i = 1; i < uis.size(); i++) {
((TextUI) (uis.elementAt(i))).modelToView2D(a,b,c);
}
return returnValue;
}
/**
* Invokes the <code>getNextVisualPositionFrom</code> method on each UI handled by this object.
*
* @return the value obtained from the first UI, which is
* the UI obtained from the default <code>LookAndFeel</code>
*/
public int getNextVisualPositionFrom(JTextComponent a, int b, Position.Bias c, int d, Position.Bias[] e)
throws BadLocationException {
int returnValue =
((TextUI) (uis.elementAt(0))).getNextVisualPositionFrom(a,b,c,d,e);
for (int i = 1; i < uis.size(); i++) {
((TextUI) (uis.elementAt(i))).getNextVisualPositionFrom(a,b,c,d,e);
}
return returnValue;
}