KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > languages > features > MyFirstDrawLayer


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.modules.languages.features;
21
22 import java.util.List JavaDoc;
23 import java.util.ListIterator JavaDoc;
24 import java.util.Set JavaDoc;
25 import javax.swing.text.AttributeSet JavaDoc;
26 import javax.swing.text.StyleConstants JavaDoc;
27 import java.awt.*;
28 import java.util.Iterator JavaDoc;
29 import javax.swing.text.Document JavaDoc;
30 import org.netbeans.api.languages.ASTItem;
31 import org.netbeans.api.languages.Highlighting;
32 import org.netbeans.api.languages.LanguagesManager;
33 import org.netbeans.api.languages.ParseException;
34 import org.netbeans.api.languages.ASTPath;
35 import org.netbeans.api.languages.ASTToken;
36 import org.netbeans.api.languages.Context;
37 import org.netbeans.api.editor.settings.EditorStyleConstants;
38 import org.netbeans.api.languages.SyntaxContext;
39 import org.netbeans.api.lexer.Token;
40 import org.netbeans.api.lexer.TokenSequence;
41 import org.netbeans.editor.DrawContext;
42 import org.netbeans.editor.DrawLayer;
43 import org.netbeans.editor.MarkFactory;
44 import org.netbeans.modules.editor.NbEditorDocument;
45 import org.netbeans.api.languages.ASTNode;
46 import org.netbeans.api.languages.ParseException;
47 import org.netbeans.api.languages.ASTToken;
48 import org.netbeans.api.lexer.TokenHierarchy;
49 import org.netbeans.modules.languages.Language;
50 import org.netbeans.modules.languages.LanguagesManagerImpl;
51 import org.netbeans.modules.languages.ParserManagerImpl;
52
53 /**
54  *
55  * @author Jan Jancura
56  */

57 public class MyFirstDrawLayer implements DrawLayer {
58
59     private String JavaDoc mimeType;
60     private Highlighting highlighting;
61     
62     
63     /** Construct new abstract layer with the known name and visibility. */
64     public MyFirstDrawLayer (String JavaDoc mimeType) {
65         this.mimeType = mimeType;
66     }
67
68     public String JavaDoc getName () {
69         return getClass ().getName ();
70     }
71
72     public boolean extendsEOL () {
73         return false;
74     }
75
76     public boolean extendsEmptyLine () {
77         return false;
78     }
79
80     public int getNextActivityChangeOffset (DrawContext ctx) {
81         return nextActivityChangeOffset;
82     }
83
84     public void init (DrawContext ctx) {
85         highlighting = Highlighting.getHighlighting
86             (ctx.getEditorUI ().getDocument ());
87     }
88
89     public int updateLineNumberContext (int lineNumber, DrawContext ctx) {
90         return lineNumber;
91     }
92
93     public String JavaDoc toString () {
94         return "Layer " + getClass (); // NOI18N
95
}
96
97     public boolean isActive (DrawContext ctx, MarkFactory.DrawMark mark) {
98         setNextActivityChangeOffset (ctx.getTokenOffset () + ctx.getTokenLength ());
99         return true;
100     }
101
102     public void updateContext (DrawContext ctx) {
103         NbEditorDocument doc = (NbEditorDocument) ctx.getEditorUI ().getDocument ();
104
105         ASTNode ast = null;
106         try {
107             ast = ParserManagerImpl.get (doc).getAST ();
108         } catch (ParseException ex) {
109             ast = ex.getASTNode ();
110         }
111         if (ast == null) {
112             markToken (ctx, doc);
113             return;
114         }
115         ASTPath path = ast.findPath (ctx.getFragmentOffset ());
116         if (path == null) {
117             markToken (ctx, doc);
118             return;
119         }
120
121         boolean isTrailing = isTrailing (path, ctx.getFragmentOffset ());
122         ASTNode splitNode = isTrailing ? splitNode (path) : null;
123         int i, k = path.size ();
124         for ( i = 0; i < k; i++) {
125             ASTItem item = path.get (i);
126             if (isTrailing && splitNode == item) {
127                 break;
128             }
129             try {
130                 Language language = ((LanguagesManagerImpl) LanguagesManager.getDefault ()).
131                     getLanguage (item.getMimeType ());
132                 AttributeSet JavaDoc as = null;
133                 List JavaDoc<AttributeSet JavaDoc> colors = ColorsManager.getColors (language, path.subPath (i), doc);
134                 //List colors = (List) language.getFeature (Language.COLOR, path.subPath (i));
135
if (colors != null) {
136                     for (Iterator JavaDoc<AttributeSet JavaDoc> it = colors.iterator (); it.hasNext ();) {
137                         as = it.next ();
138                         apply (as, ctx);
139                     }
140                 }
141                 as = highlighting.get (item);
142                 if (as != null)
143                     apply (as, ctx);
144             } catch (ParseException ex) {
145             }
146         }
147     }
148
149     private static boolean isTrailing (ASTPath path, int offset) {
150         try {
151             if (path.size () < 2 ||
152                 !(path.get (path.size () - 2) instanceof ASTNode)
153             )
154                 return false;
155             ASTNode lastNode = (ASTNode) path.get (path.size () - 2);
156             Language language = ((LanguagesManagerImpl) LanguagesManager.getDefault ()).
157                 getLanguage (lastNode.getMimeType ());
158             Set JavaDoc skipTokens = language.getSkipTokenTypes();
159             if (!(path.getLeaf () instanceof ASTToken)) {
160 // System.out.println("path does not end by token " + offset + " : " + path);
161
return false;
162             }
163             ASTToken leaf = (ASTToken) path.getLeaf ();
164             ASTNode split = null;
165             if (!skipTokens.contains (leaf.getType ()))
166                 return false;
167             split = (ASTNode) path.getRoot();
168             int size = path.size ();
169             List JavaDoc<ASTItem> list = lastNode.getChildren ();
170             for (ListIterator JavaDoc<ASTItem> iter = list.listIterator (list.size ()); iter.hasPrevious (); ) {
171                 ASTItem item = iter.previous ();
172                 if (item == leaf)
173                     return true;
174                 if (!(item instanceof ASTToken) ||
175                     !skipTokens.contains (((ASTToken) item).getType ())
176                 )
177                     break;
178             } // for
179
} catch (ParseException ex) {
180         }
181         return false;
182     }
183
184     private static ASTNode splitNode (ASTPath path) {
185         Iterator JavaDoc iter = path.listIterator ();
186         Object JavaDoc o = iter.next();
187         while (o instanceof ASTNode) {
188             List JavaDoc children = ((ASTNode)o).getChildren ();
189             o = iter.next();
190             if (!(o instanceof ASTNode)) {
191                 break;
192             }
193             if (children.get (children.size () - 1) != o) {
194                 return (ASTNode) o;
195             }
196         } // while
197
return null;
198     }
199     
200     private void markToken (DrawContext ctx, Document JavaDoc doc) {
201         TokenHierarchy hierarchy = TokenHierarchy.get (doc);
202         TokenSequence ts = hierarchy.tokenSequence ();
203         AttributeSet JavaDoc as = null;
204         do {
205             ts.move (ctx.getFragmentOffset ());
206             ts.moveNext ();
207             Token t = ts.token ();
208             if (t == null) return;
209             ASTToken stoken = ASTToken.create (
210                 ts.language ().mimeType (),
211                 t.id ().name (),
212                 t.text ().toString (),
213                 ts.offset ()
214             );
215             as = highlighting.get (stoken);
216             ts = ts.embedded ();
217         } while (as == null && ts != null);
218         if (as != null)
219             apply (as, ctx);
220     }
221     
222     /** Next position where the layer should be notified
223     * to update its state.
224     */

225     private int nextActivityChangeOffset = Integer.MAX_VALUE;
226
227     private void setNextActivityChangeOffset (int nextActivityChangeOffset) {
228         this.nextActivityChangeOffset = nextActivityChangeOffset;
229     }
230     
231     private static void apply (AttributeSet JavaDoc as, DrawContext ctx) {
232         Color c = (Color) as.getAttribute (StyleConstants.Background);
233         if (c != null) ctx.setBackColor (c);
234         c = (Color) as.getAttribute (StyleConstants.Foreground);
235         if (c != null) ctx.setForeColor (c);
236         c = (Color) as.getAttribute (StyleConstants.StrikeThrough);
237         if (c != null) ctx.setStrikeThroughColor (c);
238         c = (Color) as.getAttribute (StyleConstants.Underline);
239         if (c != null) ctx.setUnderlineColor (c);
240         c = (Color) as.getAttribute (EditorStyleConstants.WaveUnderlineColor);
241         if (c != null) ctx.setWaveUnderlineColor (c);
242         String JavaDoc fontName = (String JavaDoc) as.getAttribute (StyleConstants.FontFamily);
243         Boolean JavaDoc bold = (Boolean JavaDoc) as.getAttribute (StyleConstants.Bold);
244         Boolean JavaDoc italic = (Boolean JavaDoc) as.getAttribute (StyleConstants.Italic);
245         if (fontName != null || bold != null || italic != null) {
246             Font f = ctx.getFont ();
247             if (fontName == null) fontName = f.getFamily ();
248             if (bold == null) bold = f.isBold () ? Boolean.TRUE : Boolean.FALSE;
249             if (italic == null) italic = f.isItalic () ? Boolean.TRUE : Boolean.FALSE;
250             f = new Font (
251                 fontName,
252                 (bold.booleanValue () ? Font.BOLD : 0) +
253                     (italic.booleanValue () ? Font.ITALIC : 0),
254                 f.getSize ()
255             );
256             ctx.setFont (f);
257         }
258     }
259 }
260
261
262
Popular Tags