![JAR search and dependency download from the Maven repository](/logo.png)
org.netbeans.editor.Mark Maven / Gradle / Ivy
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.editor;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.Position;
/**
* Marks hold the relative position in the document.
*
* @author Miloslav Metelka
* @version 1.00
*/
/** Class defining basic type of mark. This is a mark used most frequently.
* It's instances are inserted into the leaf plane of the tree.
*/
public class Mark {
private static final MarkComparator MARK_COMPARATOR = new MarkComparator();
/** Document to which this mark belongs. */
private BaseDocument doc;
/** MultiMark to which this mark delegates. */
private MultiMark multiMark;
/** Bias of the mark. It is either
* {@link javax.swing.text.Position.Bias.Forward}
* or {@link javax.swing.text.Position.Bias.Backward}
*/
private Position.Bias bias;
/** Construct new mark with forward bias. */
public Mark() {
this(Position.Bias.Forward);
}
public Mark(Position.Bias bias) {
this.bias = bias;
}
/** Construct new mark.
* @param backwardBias whether the inserts performed right at the position
* of this mark will go after this mark i.e. this mark will not move
* forward when inserting right at its position. This flag corresponds
* to Position.Bias.Backward.
*/
public Mark(boolean backwardBias) {
this(backwardBias ? Position.Bias.Backward : Position.Bias.Forward);
}
void insert(BaseDocument doc, int offset) throws InvalidMarkException, BadLocationException {
BaseDocument ldoc = this.doc;
if (ldoc != null) {
throw new InvalidMarkException("Mark already inserted: mark=" + this // NOI18N
+ ", class=" + this.getClass()); // NOI18N
}
this.doc = doc;
ldoc = this.doc;
Map docMarks = ldoc.marks;
synchronized (docMarks) {
if (multiMark != null) {
throw new IllegalStateException("Mark already inserted: mark=" + this // NOI18N
+ ", class=" + this.getClass()); // NOI18N
}
if (offset < 0 || offset > ldoc.getLength() + 1) { // doc.getEndPosition() is valid
throw new BadLocationException("Invalid offset", offset); // NOI18N
}
multiMark = doc.marksStorage.createBiasMark(offset, bias);
doc.marksStorage.insert(multiMark);
docMarks.put(multiMark, this);
// checkMarks(docMarks);
}
}
private void checkMarks(Map docMarks) {
for (Iterator it = docMarks.entrySet().iterator(); it.hasNext();) {
Map.Entry me = (Map.Entry)it.next();
MultiMark mm = (MultiMark)me.getKey();
Mark m = (Mark)me.getValue();
if (m.multiMark != mm) {
throw new IllegalStateException("m.class" + m.getClass() + " mapped to wrong mark=" + mm); // NOI18N
}
}
}
void move(BaseDocument doc, int newOffset) throws InvalidMarkException, BadLocationException {
dispose();
insert(doc, newOffset);
}
/** Get the position of this mark */
public final int getOffset() throws InvalidMarkException {
BaseDocument ldoc = doc;
if (ldoc != null) {
Map docMarks = ldoc.marks;
synchronized (docMarks) {
if (multiMark != null) {
return multiMark.getOffset();
} else {
throw new InvalidMarkException();
}
}
} else {
throw new InvalidMarkException();
}
}
/** Get the line number of this mark */
public final int getLine() throws InvalidMarkException {
BaseDocument ldoc = doc;
if (ldoc != null) {
Map docMarks = ldoc.marks;
synchronized (docMarks) {
if (multiMark != null) {
int offset = multiMark.getOffset();
Element lineRoot = ldoc.getParagraphElement(0).getParentElement();
return lineRoot.getElementIndex(offset);
} else {
throw new InvalidMarkException();
}
}
} else {
throw new InvalidMarkException();
}
}
/** Get the insertAfter flag.
* Replaced by {@link #getBackwardBias()}
* @deprecated
*/
public final boolean getInsertAfter() {
return (bias == Position.Bias.Backward);
}
/** @return true if the mark has backward bias or false if it has forward bias.
*/
public final boolean getBackwardBias() {
return getInsertAfter();
}
/** @return the bias of this mark. It will be either
* {@link javax.swing.text.Position.Bias.Forward}
* or {@link javax.swing.text.Position.Bias.Backward}.
*/
public final Position.Bias getBias() {
return bias;
}
int getBiasAsInt() {
return (bias == Position.Bias.Backward) ? -1 : +1;
}
/** Mark will no longer represent a valid place in the document.
* Although it will not be removed from the structure that holds
* the marks it will be done later automatically.
*/
public final void dispose() {
BaseDocument ldoc = doc;
if (ldoc != null) {
Map docMarks = ldoc.marks;
synchronized (docMarks) {
if (multiMark != null) {
if (docMarks.remove(multiMark) != this) {
throw new IllegalStateException("Mark cannot be disposed mark=" + this + ", class=" + getClass()); // NOI18N
}
multiMark.dispose();
multiMark = null;
// checkMarks(docMarks);
this.doc = null;
return;
}
}
}
throw new IllegalStateException("Mark already disposed: mark=" + this // NOI18N
+ ", class=" + this.getClass()); // NOI18N
}
/** Remove mark from the structure holding the marks. The mark can
* be inserted again into some document.
*/
public final void remove() throws InvalidMarkException {
dispose();
}
/** Compare this mark to some position.
* @param pos tested position
* @return zero - if the marks have the same position
* less than zero - if this mark is before the position
* greater than zero - if this mark is after the position
*/
public final int compare(int pos) throws InvalidMarkException {
return getOffset() - pos;
}
/** This function is called from removeUpdater when mark occupies
* the removal area. The mark can decide what to do next.
* If it doesn't redefine this method it will be simply moved to
* the begining of removal area. It is valid to add or remove other mark
* from this method. It is even possible (but not very useful)
* to add the mark to the removal area. However that mark will not be
* notified about current removal.
* @deprecated It will not be supported in the future.
*/
protected void removeUpdateAction(int pos, int len) {
}
/** @return true if this mark is currently inserted in the document
* or false otherwise.
*/
public final boolean isValid() {
BaseDocument ldoc = doc;
if (ldoc != null) {
Map docMarks = ldoc.marks;
synchronized (docMarks) {
return (multiMark != null && multiMark.isValid());
}
}
return false;
}
/** Get info about Mark
. */
public String toString() {
return "offset=" + (isValid() ? Integer.toString(multiMark.getOffset()) : "") // NOI18N
+ ", bias=" + bias; // NOI18N
}
private static final class MarkComparator implements Comparator {
public int compare(Object o1, Object o2) {
Mark m1 = ((Mark)o1);
Mark m2 = ((Mark)o2);
try {
int offDiff = m1.getOffset() - m2.getOffset();
if (offDiff != 0) {
return offDiff;
} else {
return m1.getBiasAsInt() - m2.getBiasAsInt();
}
} catch (InvalidMarkException e) {
throw new IllegalStateException(e.toString());
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy