KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > text > link > TabStopIterator


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.text.link;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collections JavaDoc;
15 import java.util.Comparator JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.NoSuchElementException JavaDoc;
19
20 import org.eclipse.core.runtime.Assert;
21
22 import org.eclipse.jface.text.Position;
23 import org.eclipse.jface.text.link.LinkedPosition;
24
25
26
27 /**
28  * Iterator that leaps over the double occurrence of an element when switching from forward
29  * to backward iteration that is shown by <code>ListIterator</code>.
30  * <p>
31  * Package private, only for use by LinkedModeUI.
32  * </p>
33  * @since 3.0
34  */

35 class TabStopIterator {
36     /**
37      * Comparator for <code>LinkedPosition</code>s. If the sequence number of two positions is equal, the
38      * offset is used.
39      */

40     private static class SequenceComparator implements Comparator JavaDoc {
41
42         /**
43          * {@inheritDoc}
44          *
45          * <p><code>o1</code> and <code>o2</code> are required to be instances
46          * of <code>LinkedPosition</code>.</p>
47          */

48         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
49             LinkedPosition p1= (LinkedPosition)o1;
50             LinkedPosition p2= (LinkedPosition)o2;
51             int i= p1.getSequenceNumber() - p2.getSequenceNumber();
52             if (i != 0)
53                 return i;
54             return p1.getOffset() - p2.getOffset();
55         }
56
57     }
58
59     /** The comparator to sort the list of positions. */
60     private static final Comparator JavaDoc fComparator= new SequenceComparator();
61
62     /** The iteration sequence. */
63     private final ArrayList JavaDoc fList;
64     /** The size of <code>fList</code>. */
65     private int fSize;
66     /** Index of the current element, to the first one initially. */
67     private int fIndex;
68     /** Cycling property. */
69     private boolean fIsCycling= false;
70
71     TabStopIterator(List JavaDoc positionSequence) {
72         Assert.isNotNull(positionSequence);
73         fList= new ArrayList JavaDoc(positionSequence);
74         Collections.sort(fList, fComparator);
75         fSize= fList.size();
76         fIndex= -1;
77         Assert.isTrue(fSize > 0);
78     }
79
80     boolean hasNext(LinkedPosition current) {
81         return getNextIndex(current) != fSize;
82     }
83
84     private int getNextIndex(LinkedPosition current) {
85         if (current != null && fList.get(fIndex) != current)
86             return findNext(current);
87         else if (fIsCycling && fIndex == fSize - 1)
88             return 0;
89         else
90             // default: increase
91
return fIndex + 1;
92     }
93
94     /**
95      * Finds the closest position in the iteration set that follows after
96      * <code>current</code> and sets <code>fIndex</code> accordingly. If <code>current</code>
97      * is in the iteration set, the next in turn is chosen.
98      *
99      * @param current the current position
100      * @return <code>true</code> if there is a next position, <code>false</code> otherwise
101      */

102     private int findNext(LinkedPosition current) {
103         Assert.isNotNull(current);
104         // if the position is in the iteration set, jump to the next one
105
int index= fList.indexOf(current);
106         if (index != -1) {
107             if (fIsCycling && index == fSize - 1)
108                 return 0;
109             return index + 1;
110         }
111
112         // index == -1
113

114         // find the position that follows closest to the current position
115
LinkedPosition found= null;
116         for (Iterator JavaDoc it= fList.iterator(); it.hasNext(); ) {
117             LinkedPosition p= (LinkedPosition) it.next();
118             if (p.offset > current.offset)
119                 if (found == null || found.offset > p.offset)
120                     found= p;
121         }
122
123         if (found != null) {
124             return fList.indexOf(found);
125         } else if (fIsCycling) {
126             return 0;
127         } else
128             return fSize;
129     }
130
131     boolean hasPrevious(LinkedPosition current) {
132         return getPreviousIndex(current) != -1;
133     }
134
135     private int getPreviousIndex(LinkedPosition current) {
136         if (current != null && fList.get(fIndex) != current)
137             return findPrevious(current);
138         else if (fIsCycling && fIndex == 0)
139             return fSize - 1;
140         else
141             return fIndex - 1;
142     }
143
144     /**
145      * Finds the closest position in the iteration set that precedes
146      * <code>current</code>. If <code>current</code>
147      * is in the iteration set, the previous in turn is chosen.
148      *
149      * @param current the current position
150      * @return the index of the previous position
151      */

152     private int findPrevious(LinkedPosition current) {
153         Assert.isNotNull(current);
154         // if the position is in the iteration set, jump to the next one
155
int index= fList.indexOf(current);
156         if (index != -1) {
157             if (fIsCycling && index == 0)
158                 return fSize - 1;
159             return index - 1;
160         }
161
162         // index == -1
163

164         // find the position that follows closest to the current position
165
LinkedPosition found= null;
166         for (Iterator JavaDoc it= fList.iterator(); it.hasNext(); ) {
167             LinkedPosition p= (LinkedPosition) it.next();
168             if (p.offset < current.offset)
169                 if (found == null || found.offset < p.offset)
170                     found= p;
171         }
172         if (found != null) {
173             return fList.indexOf(found);
174         } else if (fIsCycling) {
175             return fSize - 1;
176         } else
177             return -1;
178     }
179
180     LinkedPosition next(LinkedPosition current) {
181         if (!hasNext(current))
182             throw new NoSuchElementException JavaDoc();
183         return (LinkedPosition) fList.get(fIndex= getNextIndex(current));
184     }
185
186     LinkedPosition previous(LinkedPosition current) {
187         if (!hasPrevious(current))
188             throw new NoSuchElementException JavaDoc();
189         return (LinkedPosition) fList.get(fIndex= getPreviousIndex(current));
190     }
191
192     void setCycling(boolean mode) {
193         fIsCycling= mode;
194     }
195
196     void addPosition(Position position) {
197         fList.add(fSize++, position);
198         Collections.sort(fList, fComparator);
199     }
200
201     void removePosition(Position position) {
202         if (fList.remove(position))
203             fSize--;
204     }
205
206     /**
207      * @return Returns the isCycling.
208      */

209     boolean isCycling() {
210         return fIsCycling;
211     }
212
213     LinkedPosition[] getPositions() {
214         return (LinkedPosition[]) fList.toArray(new LinkedPosition[fSize]);
215     }
216 }
217
Popular Tags