KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > text > AttributedCharacters


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.openide.text;
20
21 import java.awt.Color JavaDoc;
22 import java.awt.Font JavaDoc;
23 import java.awt.font.TextAttribute JavaDoc;
24
25 import java.text.AttributedCharacterIterator JavaDoc;
26
27 import java.util.Collections JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Set JavaDoc;
32
33
34 /** The class is a support for all classes that implement PrintCookie.
35 * Allows creating of attributed texts.
36 *
37 * @author Ales Novak
38 */

39 public class AttributedCharacters extends Object JavaDoc {
40     /** Characters to iterate. */
41     protected char[] chars;
42
43     /** Font for each character. */
44     protected Font JavaDoc[] fonts;
45
46     /** Color for each character. */
47     protected Color JavaDoc[] colors;
48
49     /** Start indices of continuous blocks of text with the same font. */
50     protected int[] runStart;
51
52     /** Limit indices of continous ... */
53     protected int[] runLimit;
54
55     /** Current. */
56     protected int current;
57
58     public AttributedCharacters() {
59         chars = new char[10];
60         fonts = new Font JavaDoc[10];
61         colors = new Color JavaDoc[10];
62         runStart = new int[10];
63         runLimit = new int[10];
64         current = -1;
65     }
66
67     /** Append a character with specified font.
68      * @param c character to append
69      * @param f a Font
70      * @param color a Color
71      */

72     public void append(char c, Font JavaDoc f, Color JavaDoc color) {
73         if (f == null) {
74             return;
75         }
76
77         if (++current == chars.length) {
78             char[] ctmp = new char[2 * chars.length];
79             Font JavaDoc[] ftmp = new Font JavaDoc[2 * chars.length];
80             Color JavaDoc[] cotmp = new Color JavaDoc[2 * chars.length];
81             int[] rstmp = new int[2 * chars.length];
82             int[] rltmp = new int[2 * chars.length];
83             System.arraycopy(chars, 0, ctmp, 0, chars.length);
84             System.arraycopy(fonts, 0, ftmp, 0, chars.length);
85             System.arraycopy(colors, 0, cotmp, 0, chars.length);
86             System.arraycopy(runStart, 0, rstmp, 0, chars.length);
87             System.arraycopy(runLimit, 0, rltmp, 0, chars.length);
88             chars = ctmp;
89             fonts = ftmp;
90             colors = cotmp;
91             runStart = rstmp;
92             runLimit = rltmp;
93         }
94
95         chars[current] = c;
96         fonts[current] = f;
97         colors[current] = color;
98
99         if (current != 0) {
100             int prev = current - 1;
101
102             if (fonts[prev].equals(f) && colors[prev].equals(color)) {
103                 runLimit[runStart[current] = runStart[prev]] = current;
104             } else {
105                 runLimit[current] = current;
106                 runStart[current] = current;
107             }
108         }
109     }
110
111     /** Append a character array with a font.
112      * @param a characters to append
113      * @param f a font to use
114      * @param color a color to use
115      */

116     public void append(char[] a, Font JavaDoc f, Color JavaDoc color) {
117         if ((a == null) || (a.length == 0) || (f == null) || (color == null)) {
118             return;
119         }
120
121         // increase buffers
122
if ((++current + a.length) >= chars.length) {
123             int size = Math.max(current + a.length, 2 * chars.length);
124             char[] ctmp = new char[size];
125             Font JavaDoc[] ftmp = new Font JavaDoc[size];
126             Color JavaDoc[] cotmp = new Color JavaDoc[size];
127             int[] rstmp = new int[size];
128             int[] rltmp = new int[size];
129             System.arraycopy(chars, 0, ctmp, 0, chars.length);
130             System.arraycopy(fonts, 0, ftmp, 0, fonts.length);
131             System.arraycopy(colors, 0, cotmp, 0, chars.length);
132             System.arraycopy(runStart, 0, rstmp, 0, chars.length);
133             System.arraycopy(runLimit, 0, rltmp, 0, chars.length);
134             chars = ctmp;
135             fonts = ftmp;
136             colors = cotmp;
137             runStart = rstmp;
138             runLimit = rltmp;
139         }
140
141         // fill buffers
142
System.arraycopy(a, 0, chars, current, a.length);
143
144         for (int i = 0; i < a.length; i++) {
145             fonts[i + current] = f;
146             colors[i + current] = color;
147         }
148
149         // update last member to be the runLimit for the first one in the block
150
int prev = current - 1;
151         int pseudo = (current + a.length) - 1;
152
153         if (prev < 0) { // start?
154
runLimit[0] = pseudo;
155         } else {
156             int replace;
157
158             if (fonts[prev].equals(f) && colors[prev].equals(color)) { // increase old block
159
runLimit[runStart[prev]] = pseudo;
160                 replace = runStart[prev];
161             } else { // new block
162
runLimit[current] = pseudo;
163                 replace = current;
164             }
165
166             // init items in the block - update runStart
167
for (int i = current; i <= pseudo; i++) {
168                 runStart[i] = replace;
169             }
170         }
171
172         current = pseudo;
173     }
174
175     /** Produce an appropriate character iterator.
176      * @return an iterator
177      */

178     public AttributedCharacterIterator JavaDoc iterator() {
179         int size = current + 1;
180         char[] cs = new char[size];
181         Font JavaDoc[] fs = new Font JavaDoc[size];
182         Color JavaDoc[] colos = new Color JavaDoc[size];
183         int[] rstmp = new int[size];
184         int[] rltmp = new int[size];
185         System.arraycopy(runStart, 0, rstmp, 0, size);
186         System.arraycopy(runLimit, 0, rltmp, 0, size);
187         System.arraycopy(chars, 0, cs, 0, size);
188         System.arraycopy(fonts, 0, fs, 0, size);
189         System.arraycopy(colors, 0, colos, 0, size);
190
191         AttributedCharacterIterator JavaDoc ret = new AttributedCharacterIteratorImpl(cs, fs, colos, rstmp, rltmp);
192
193         return ret;
194     }
195
196     /** Implementation of AttributedCharacterIterator interface. */
197     public static class AttributedCharacterIteratorImpl implements AttributedCharacterIterator JavaDoc {
198         /** Current position. */
199         protected int current;
200
201         /** Characters to iterate. */
202         protected char[] chars;
203
204         /** Font for each character. */
205         protected Font JavaDoc[] fonts;
206
207         /** Color for each character. */
208         protected Color JavaDoc[] colors;
209
210         /** Start indices of continuous blocks of text with the same font. */
211         protected int[] runStart;
212
213         /** Limit indices of continous ... */
214         protected int[] runLimit;
215
216         /** Singleton. */
217         protected Set JavaDoc<AttributedCharacterIterator.Attribute JavaDoc> singleton;
218
219         public AttributedCharacterIteratorImpl(char[] chars, Font JavaDoc[] fonts, Color JavaDoc[] colors, int[] rs, int[] rl) {
220             this.chars = chars;
221             this.fonts = fonts;
222             this.colors = colors;
223             runStart = rs;
224             runLimit = rl;
225         }
226
227         // first implement CharacterIterator
228

229         /*
230          * Clones the object.
231          * @return a clone
232          */

233         public Object JavaDoc clone() {
234             try {
235                 return super.clone();
236             } catch (CloneNotSupportedException JavaDoc e) {
237                 // impossible to catch it
238
return null;
239             }
240         }
241
242         /*
243          * @return current char
244          */

245         public char current() {
246             if (current >= chars.length) {
247                 return DONE;
248             }
249
250             return chars[current];
251         }
252
253         /*
254          * @return first char
255          */

256         public char first() {
257             current = 0;
258
259             if (current >= chars.length) {
260                 return DONE;
261             }
262
263             return chars[current];
264         }
265
266         /*
267          * @return begin index
268          */

269         public int getBeginIndex() {
270             return 0;
271         }
272
273         /*
274          * @return end index
275          */

276         public int getEndIndex() {
277             return chars.length;
278         }
279
280         /*
281          * @return current index
282          */

283         public int getIndex() {
284             return current;
285         }
286
287         /*
288          * @return character at last index
289          */

290         public char last() {
291             int end = getEndIndex();
292
293             if (end == 0) {
294                 return DONE;
295             }
296
297             return chars[current = end - 1];
298         }
299
300         /*
301          * @return next char
302          */

303         public char next() {
304             if (current >= (getEndIndex() - 1)) {
305                 return DONE;
306             }
307
308             return chars[++current];
309         }
310
311         /*
312          * @return previous char
313          */

314         public char previous() {
315             if (current == 0) {
316                 return DONE;
317             }
318
319             return chars[--current];
320         }
321
322         /*
323          * @param i new index
324          * @return char at that position
325          */

326         public char setIndex(int i) {
327             if (i < 0) {
328                 throw new IllegalArgumentException JavaDoc();
329             }
330
331             if (i == getEndIndex()) {
332                 current = getEndIndex();
333
334                 return DONE;
335             }
336
337             return chars[current = i];
338         }
339
340         // attributes
341

342         /*
343          * @return a Set with TextAttribute.FONT
344          */

345         public Set JavaDoc<AttributedCharacterIterator.Attribute JavaDoc> getAllAttributeKeys() {
346             if (singleton == null) {
347                 Set JavaDoc<AttributedCharacterIterator.Attribute JavaDoc> l = new HashSet JavaDoc<AttributedCharacterIterator.Attribute JavaDoc>(4);
348                 l.add(TextAttribute.FONT);
349                 l.add(TextAttribute.FOREGROUND);
350                 singleton = Collections.unmodifiableSet(l);
351             }
352
353             return singleton;
354         }
355
356         /*
357          * @param att an Attribute
358          * @return a value for this attribute
359          */

360         public Object JavaDoc getAttribute(AttributedCharacterIterator.Attribute JavaDoc att) {
361             if (att == TextAttribute.FONT) {
362                 return fonts[getIndex()];
363             } else if (att == TextAttribute.FOREGROUND) {
364                 return colors[getIndex()];
365             } else {
366                 return null;
367             }
368         }
369
370         /*
371          * @return map with all attributes for current char
372          */

373         public Map JavaDoc<AttributedCharacterIterator.Attribute JavaDoc,Object JavaDoc> getAttributes() {
374             Map JavaDoc<AttributedCharacterIterator.Attribute JavaDoc,Object JavaDoc> m = new HashMap JavaDoc<AttributedCharacterIterator.Attribute JavaDoc,Object JavaDoc>(1);
375             m.put(TextAttribute.FONT, fonts[getIndex()]);
376             m.put(TextAttribute.FOREGROUND, colors[getIndex()]);
377
378             return m;
379         }
380
381         /*
382          * @return
383          */

384         public int getRunLimit() {
385             return runLimit[runStart[getIndex()]] + 1;
386         }
387
388         /*
389          * @param att an Attribute
390          */

391         public int getRunLimit(AttributedCharacterIterator.Attribute JavaDoc att) {
392             if ((att != TextAttribute.FONT) && (att != TextAttribute.FOREGROUND)) {
393                 return getEndIndex(); // undefined attribute
394
}
395
396             return getRunLimit();
397         }
398
399         /*
400          * @param attributes a Set of attributes
401          */

402         public int getRunLimit(Set JavaDoc<? extends AttributedCharacterIterator.Attribute JavaDoc> attributes) {
403             if (attributes.contains(TextAttribute.FONT) || attributes.contains(TextAttribute.FOREGROUND)) {
404                 return getRunLimit();
405             } else {
406                 return getEndIndex();
407             }
408         }
409
410         /*
411          * @return run start for current char
412          */

413         public int getRunStart() {
414             return runStart[getIndex()];
415         }
416
417         /*
418          * @param att
419          */

420         public int getRunStart(AttributedCharacterIterator.Attribute JavaDoc att) {
421             if ((att != TextAttribute.FONT) && (att != TextAttribute.FOREGROUND)) {
422                 return 0; // undefined attribute
423
}
424
425             return getRunStart();
426         }
427
428         /*
429          * @param attributes a Set
430          */

431         public int getRunStart(Set JavaDoc<? extends AttributedCharacterIterator.Attribute JavaDoc> attributes) {
432             if ((attributes.contains(TextAttribute.FONT)) || attributes.contains(TextAttribute.FOREGROUND)) {
433                 return getRunStart();
434             } else {
435                 return 0;
436             }
437         }
438     }
439 }
440
Popular Tags