2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.lib.editor.util.swing;
44
import java.util.Comparator;
45
import java.util.List;
46
import javax.swing.text.BadLocationException;
47
import javax.swing.text.Document;
48
import javax.swing.text.Position;
51
* A pair of positions delimiting a text region in a swing document.
53
* At all times it should be satisfied that
54
* {@link #getStartOffset()} <= {@link #getEndOffset()}.
56
* @author Miloslav Metelka
60
public class PositionRegion {
62
/** Copmarator for position regions */
63
private static Comparator<PositionRegion> comparator;
66
* Get comparator for position regions comparing start offsets
67
* of the two given regions.
69
* @return non-null comparator comparing the start offsets of the two given
72
public static final Comparator<PositionRegion> getComparator() {
73
if (comparator == null) {
74
comparator = new Comparator<PositionRegion>() {
75
public int compare(PositionRegion pr1, PositionRegion pr2) {
76
return pr1.getStartOffset() - pr2.getStartOffset();
84
* Create a fixed position instance that just wraps a given integer offset.
86
* This may be useful for situations where a position needs to be used
87
* but the document is not available yet. Once the document becomes
88
* available the regular position instance (over an existing document)
89
* may be used instead.
91
* @param offset >=0 offset at which the position should be created.
94
public static Position createFixedPosition(final int offset) {
96
throw new IllegalArgumentException("offset < 0");
98
return new Position() {
99
public int getOffset() {
106
* Check whether a list of position regions is sorted
107
* according the start offsets of the regions.
109
* @param positionRegionList list of the regions to be compared.
110
* @return true if the regions are sorted according to the starting offset
111
* of the given regions or false otherwise.
113
public static boolean isRegionsSorted(List<? extends PositionRegion> positionRegionList) {
114
for (int i = positionRegionList.size() - 2; i >= 0; i--) {
115
if (getComparator().compare(positionRegionList.get(i),
116
positionRegionList.get(i + 1)) > 0) {
123
private Position startPosition;
125
private Position endPosition;
128
* Construct new position region.
130
* @param startPosition non-null start position of the region <= end position.
131
* @param endPosition non-null end position of the region >= start position.
133
public PositionRegion(Position startPosition, Position endPosition) {
134
assertPositionsValid(startPosition, endPosition);
135
this.startPosition = startPosition;
136
this.endPosition = endPosition;
140
* Construct new position region based on the knowledge
141
* of the document and starting and ending offset.
143
public PositionRegion(Document doc, int startOffset, int endOffset) throws BadLocationException {
144
this(doc.createPosition(startOffset), doc.createPosition(endOffset));
148
* Get starting offset of this region.
150
* @return >=0 starting offset of this region.
152
public final int getStartOffset() {
153
return startPosition.getOffset();
157
* Get starting position of this region.
159
* @return non-null starting position of this region.
161
public final Position getStartPosition() {
162
return startPosition;
166
* Get ending offset of this region.
168
* @return >=0 ending offset of this region.
170
public final int getEndOffset() {
171
return endPosition.getOffset();
175
* Get ending position of this region.
177
* @return non-null ending position of this region.
179
public final Position getEndPosition() {
184
* Get length of this region.
186
* @return >=0 length of this region
187
* computed as <code>getEndOffset() - getStartOffset()</code>.
189
public final int getLength() {
190
return getEndOffset() - getStartOffset();
194
* {@link MutablePositionRegion} uses this package private method
195
* to set a new start position of this region.
197
void resetImpl(Position startPosition, Position endPosition) {
198
assertPositionsValid(startPosition, endPosition);
199
this.startPosition = startPosition;
200
this.endPosition = endPosition;
204
* {@link MutablePositionRegion} uses this package private method
205
* to set a new start position of this region.
207
void setStartPositionImpl(Position startPosition) {
208
assertPositionsValid(startPosition, endPosition);
209
this.startPosition = startPosition;
213
* {@link MutablePositionRegion} uses this package private method
214
* to set a new start position of this region.
216
void setEndPositionImpl(Position endPosition) {
217
assertPositionsValid(startPosition, endPosition);
218
this.endPosition = endPosition;
221
private static void assertPositionsValid(Position startPos, Position endPos) {
222
assert (startPos.getOffset() <= endPos.getOffset())
223
: "startPosition=" + startPos.getOffset() + " > endPosition=" // NOI18N
224
+ endPos.getOffset();