KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > editor > ext > java > JavaDrawLayerFactory


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
20 package org.netbeans.editor.ext.java;
21
22 import java.util.List JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import javax.swing.text.BadLocationException JavaDoc;
25 import javax.swing.event.DocumentListener JavaDoc;
26 import javax.swing.event.DocumentEvent JavaDoc;
27
28 import org.netbeans.editor.*;
29 import org.netbeans.editor.ext.ExtSyntaxSupport;
30
31 /**
32 * Various java-layers
33 *
34 * @author Miloslav Metelka
35 * @version 1.00
36 */

37
38 public class JavaDrawLayerFactory {
39
40     public static final String JavaDoc JAVA_LAYER_NAME = "java-layer"; // NOI18N
41

42     public static final int JAVA_LAYER_VISIBILITY = 1010;
43
44     /** Layer that colors extra java information like the methods or special
45      * characters in the character and string literals.
46      */

47     public static class JavaLayer extends DrawLayer.AbstractLayer {
48
49         /** End of the area that is resolved right now. It saves
50          * repetitive searches for '(' for multiple fragments
51          * inside one identifier token.
52          */

53         private int resolvedEndOffset;
54
55         private boolean resolvedValue;
56
57         private NonWhitespaceFwdFinder nwFinder = new NonWhitespaceFwdFinder();
58
59         public JavaLayer() {
60             super(JAVA_LAYER_NAME);
61         }
62
63         public void init(DrawContext ctx) {
64             resolvedEndOffset = 0; // nothing resolved
65
}
66
67         public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) {
68             int nextOffset = ctx.getTokenOffset() + ctx.getTokenLength();
69
70             setNextActivityChangeOffset(nextOffset);
71             return true;
72         }
73
74         protected Coloring getMethodColoring(DrawContext ctx) {
75             TokenContextPath path = ctx.getTokenContextPath().replaceStart(
76                 JavaLayerTokenContext.contextPath);
77             return ctx.getEditorUI().getColoring(
78                 path.getFullTokenName(JavaLayerTokenContext.METHOD));
79         }
80
81         private boolean isMethod(DrawContext ctx) {
82             int idEndOffset = ctx.getTokenOffset() + ctx.getTokenLength();
83             if (idEndOffset > resolvedEndOffset) { // beyond the resolved area
84
resolvedEndOffset = idEndOffset; // will resolve now
85
int endOffset = ctx.getEndOffset();
86                 int bufferStartOffset = ctx.getBufferStartOffset();
87                 char[] buffer = ctx.getBuffer();
88                 ExtSyntaxSupport sup = (ExtSyntaxSupport) ctx.getEditorUI().getDocument().getSyntaxSupport().get(ExtSyntaxSupport.class);
89                 int nwOffset = Analyzer.findFirstNonWhite(buffer,
90                         idEndOffset - bufferStartOffset,
91                         endOffset - idEndOffset);
92                 if (nwOffset >= 0) { // found non-white
93
resolvedValue = (buffer[nwOffset] == '(');
94                     if (!resolvedValue && buffer[nwOffset] == '<') {
95                         try {
96                             int[] block = sup.findMatchingBlock(ctx.getBufferStartOffset() + nwOffset, true);
97                             if (block != null) {
98                                 int off = Utilities.getFirstNonWhiteFwd(ctx.getEditorUI().getDocument(), block[1]);
99                                 if (off > -1) {
100                                     if (bufferStartOffset + buffer.length > off) {
101                                         resolvedValue = (buffer[off - bufferStartOffset] == '(');
102                                     } else {
103                                         resolvedValue = (ctx.getEditorUI().getDocument().getChars(off, 1)[0] == '(');
104                                     }
105                                 }
106                             }
107                         } catch (BadLocationException JavaDoc e) {
108                             resolvedValue = false;
109                         }
110                     }
111                 } else { // must resolve after buffer end
112
try {
113                         int off = ctx.getEditorUI().getDocument().find(nwFinder, endOffset, -1);
114                         resolvedValue = off >= 0 && (nwFinder.getFoundChar() == '(');
115                         if (!resolvedValue && nwFinder.getFoundChar() == '<') {
116                             int[] block = sup.findMatchingBlock(off, true);
117                             if (block != null) {
118                                 off = Utilities.getFirstNonWhiteFwd(ctx.getEditorUI().getDocument(), block[1]);
119                                 if (off > -1)
120                                     resolvedValue = (ctx.getEditorUI().getDocument().getChars(off, 1)[0] == '(');
121                             }
122                         }
123                     } catch (BadLocationException JavaDoc e) {
124                         resolvedValue = false;
125                     }
126                 }
127             }
128
129             return resolvedValue;
130         }
131
132         public void updateContext(DrawContext ctx) {
133             if (ctx.getTokenID() == JavaTokenContext.IDENTIFIER && isMethod(ctx)) {
134                 Coloring mc = getMethodColoring(ctx);
135                 if (mc != null) {
136                     mc.apply(ctx);
137                 }
138             }
139         }
140
141     }
142
143     /** Find first non-white character forward */
144     static class NonWhitespaceFwdFinder extends FinderFactory.GenericFwdFinder {
145
146         private char foundChar;
147
148         public char getFoundChar() {
149             return foundChar;
150         }
151
152         protected int scan(char ch, boolean lastChar) {
153             if (!Character.isWhitespace(ch)) {
154                 found = true;
155                 foundChar = ch;
156                 return 0;
157             }
158             return 1;
159         }
160     }
161
162     /** Find first non-white character backward */
163     public static class NonWhitespaceBwdFinder extends FinderFactory.GenericBwdFinder {
164
165         private char foundChar;
166
167         public char getFoundChar() {
168             return foundChar;
169         }
170
171         protected int scan(char ch, boolean lastChar) {
172             if (!Character.isWhitespace(ch)) {
173                 found = true;
174                 foundChar = ch;
175                 return 0;
176             }
177             return -1;
178         }
179     }
180
181     /** This class watches whether the '(' character was inserted/removed.
182      * It ensures the appropriate part of the document till
183      * the previous non-whitespace will be repainted.
184      */

185     public static class LParenWatcher implements DocumentListener JavaDoc {
186
187         NonWhitespaceBwdFinder nwFinder = new NonWhitespaceBwdFinder();
188
189         private void check(DocumentEvent JavaDoc evt) {
190             if (evt.getDocument() instanceof BaseDocument) {
191                 BaseDocument doc = (BaseDocument)evt.getDocument();
192                 BaseDocumentEvent bevt = (BaseDocumentEvent)evt;
193                 String JavaDoc text = bevt.getText();
194                 if (text != null) {
195                     boolean found = false;
196                     for (int i = text.length() - 1; i >= 0; i--) {
197                         if (text.charAt(i) == '(') {
198                             found = true;
199                             break;
200                         }
201                     }
202
203                     if (found) {
204                         int offset = evt.getOffset();
205                         // Need to repaint
206
int redrawOffset = 0;
207                         if (offset > 0) {
208                             try {
209                                 redrawOffset = doc.find(nwFinder, offset - 1, 0);
210                             } catch (BadLocationException JavaDoc e) {
211                             }
212
213                             if (redrawOffset < 0) { // not found non-whitespace
214
redrawOffset = 0;
215                             }
216                         }
217                         doc.repaintBlock(redrawOffset, offset);
218                     }
219                 }
220             }
221         }
222
223         public void insertUpdate(DocumentEvent JavaDoc evt) {
224             check(evt);
225         }
226
227         public void removeUpdate(DocumentEvent JavaDoc evt) {
228             check(evt);
229         }
230
231         public void changedUpdate(DocumentEvent JavaDoc evt) {
232         }
233
234     }
235
236 }
237
238
Popular Tags