KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > gsf > browser > HighlightSections


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.netbeans.modules.gsf.browser;
20
21 import java.awt.Color JavaDoc;
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.beans.PropertyChangeSupport JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Set JavaDoc;
27
28 import javax.swing.SwingUtilities JavaDoc;
29 import javax.swing.text.BadLocationException JavaDoc;
30 import javax.swing.text.Document JavaDoc;
31 import javax.swing.text.JTextComponent JavaDoc;
32
33 import org.netbeans.api.gsf.ParserResult;
34 import org.netbeans.editor.BaseDocument;
35 import org.netbeans.editor.Coloring;
36 import org.netbeans.editor.DrawContext;
37 import org.netbeans.editor.DrawLayer;
38 import org.netbeans.editor.EditorUI;
39 import org.netbeans.editor.FinderFactory;
40 import org.netbeans.editor.MarkFactory;
41 import org.netbeans.editor.Registry;
42 import org.netbeans.editor.Utilities;
43 import org.openide.util.Mutex;
44 import org.openide.util.WeakSet;
45
46
47 /**
48  * Provides support for tab highlighting.
49  * (This was based on the stripwhitespace module by Andrei Badea)
50  *
51  * @author Andrei Badea
52  * @author Tor Norbye
53  */

54 public class HighlightSections {
55     private static final HighlightSections DEFAULT = new HighlightSections();
56     private final Set JavaDoc<EditorUI> INSTALLED = new WeakSet<EditorUI>();
57     private ParserResult.AstTreeNode selectedNode;
58     private Document JavaDoc selectedDocument;
59
60     private HighlightSections() {
61     }
62
63     public static HighlightSections getDefault() {
64         return DEFAULT;
65     }
66
67     public ParserResult.AstTreeNode getSelectedNode() {
68         return selectedNode;
69     }
70     
71     public Document JavaDoc getSelectedDocument() {
72         return selectedDocument;
73     }
74
75     public void setSelectedNode(Document JavaDoc selectedDocument, ParserResult.AstTreeNode selectedNode) {
76         this.selectedDocument = selectedDocument;
77         this.selectedNode = selectedNode;
78     }
79
80     public void install(final JTextComponent JavaDoc component) {
81         if (component == null) {
82             //No editors open
83
return;
84         }
85
86         Mutex.EVENT.readAccess(new Runnable JavaDoc() {
87                 public void run() {
88                     EditorUI editorUI = Utilities.getEditorUI(component);
89
90                     if (editorUI == null) {
91                         return;
92                     }
93
94                     Layer layer = (Layer)editorUI.findLayer(Layer.NAME);
95
96                     if (layer == null) {
97                         layer = new Layer();
98                         editorUI.addLayer(layer, Layer.VISIBILITY);
99                         INSTALLED.add(editorUI);
100
101                         // needed in order to repaint the active component when the module
102
// is installed/enabled through Module Manager/Update Center
103
editorUI.repaint(0);
104                     }
105                 }
106             });
107     }
108
109     public void uninstall() {
110         Mutex.EVENT.readAccess(new Runnable JavaDoc() {
111                 public void run() {
112                     for (Iterator JavaDoc i = INSTALLED.iterator(); i.hasNext();) {
113                         EditorUI editorUI = (EditorUI)i.next();
114                         editorUI.removeLayer(Layer.NAME);
115                     }
116
117                     INSTALLED.clear();
118
119                     // repainting the active component when the module
120
// is installed/enabled through Module Manager/Update Center
121
repaintMostActiveComponent();
122                 }
123             });
124     }
125
126     public void setColor(final JTextComponent JavaDoc component, final Color JavaDoc color) {
127         Mutex.EVENT.readAccess(new Runnable JavaDoc() {
128                 public void run() {
129                     EditorUI editorUI = Utilities.getEditorUI(component);
130
131                     if (editorUI == null) {
132                         return;
133                     }
134
135                     Layer layer = (Layer)editorUI.findLayer(Layer.NAME);
136
137                     if (layer == null) {
138                         return;
139                     }
140
141                     layer.setColor(color);
142                     editorUI.repaint(0);
143                 }
144             });
145     }
146
147     private void repaintMostActiveComponent() {
148         assert SwingUtilities.isEventDispatchThread();
149
150         javax.swing.text.JTextComponent JavaDoc component = Registry.getMostActiveComponent();
151
152         if (component == null) {
153             return;
154         }
155
156         EditorUI editorUI = Utilities.getEditorUI(component);
157
158         if (editorUI != null) {
159             editorUI.repaint(0);
160         }
161     }
162
163     private static final class Layer extends DrawLayer.AbstractLayer {
164         private static final String JavaDoc NAME = "browser-highlight-layer"; // NOI18N
165

166         // just below the highlight whitespace layer (see whitespace highlighting module)
167
private static final int VISIBILITY = 7990;
168         private final Color JavaDoc HIGHLIGHTING_COLOR = new Color JavaDoc(255, 200, 255);
169         private boolean enabled = true;
170         private Coloring coloring;
171         private int[] blocks = new int[] { -1, -1 };
172         private int curInd = 0;
173
174         public Layer() {
175             super(NAME);
176         }
177
178         public void setEnabled(boolean enabled) {
179             this.enabled = enabled;
180         }
181
182         public void setColor(Color JavaDoc color) {
183             coloring = new Coloring(null, null, color);
184         }
185
186         public void colorChanged() {
187             coloring = null;
188
189             // will be recreated in updateContext
190
}
191
192         public void init(DrawContext ctx) {
193             if (!enabled) {
194                 return;
195             }
196
197             BaseDocument doc = (BaseDocument)ctx.getEditorUI().getDocument();
198             Document JavaDoc selectedDocument = HighlightSections.getDefault().getSelectedDocument();
199
200             if (doc != selectedDocument) {
201                 return;
202             }
203
204             ParserResult.AstTreeNode node = HighlightSections.getDefault().getSelectedNode();
205
206             if (node != null) {
207                 int beginNode = node.getStartOffset();
208                 int endNode = node.getEndOffset();
209                 int beginCtx = ctx.getStartOffset();
210                 int endCtx = ctx.getEndOffset();
211
212                 if (beginNode < beginCtx) {
213                     beginNode = beginCtx;
214                 }
215
216                 if (endNode > endCtx) {
217                     endNode = endCtx;
218                 }
219
220                 curInd = 0;
221
222                 int blockIndex = 0;
223
224                 try {
225                     blockIndex = addBlock(blockIndex, beginNode, endNode);
226                 } finally {
227                     blockIndex = addBlock(blockIndex, -1, -1);
228                 }
229             }
230         }
231
232         private int addBlock(int blockIndex, int start, int end) {
233             if (blockIndex > (blocks.length - 2)) {
234                 int[] newBlocks = new int[(blocks.length > 0) ? (blocks.length * 2) : 2];
235                 System.arraycopy(blocks, 0, newBlocks, 0, blocks.length);
236                 blocks = newBlocks;
237
238                 // we never shrink the blocks array, but in practice it
239
// doesn't seem to matter, because the editor calls init() for each line,
240
// so the max length of the array will be 4 (ws start, ws end, -1, -1)
241
}
242
243             blocks[blockIndex++] = start;
244             blocks[blockIndex++] = end;
245
246             return blockIndex;
247         }
248
249         public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) {
250             if (!enabled) {
251                 return false;
252             }
253
254             boolean active;
255
256             int pos = ctx.getFragmentOffset();
257
258             if (pos == blocks[curInd]) {
259                 active = true;
260                 setNextActivityChangeOffset(blocks[curInd + 1]);
261             } else if (pos == blocks[curInd + 1]) {
262                 active = false;
263                 curInd += 2;
264                 setNextActivityChangeOffset(blocks[curInd]);
265
266                 if (pos == blocks[curInd]) { // just follows
267
setNextActivityChangeOffset(blocks[curInd + 1]);
268                     active = true;
269                 }
270             } else {
271                 setNextActivityChangeOffset(blocks[curInd]);
272                 active = false;
273             }
274
275             return active;
276         }
277
278         public void updateContext(DrawContext ctx) {
279             int pos = ctx.getFragmentOffset();
280
281             if ((pos >= blocks[curInd]) && (pos < blocks[curInd + 1])) {
282                 if (coloring == null) {
283                     coloring = new Coloring(null, null, HIGHLIGHTING_COLOR);
284                 }
285
286                 coloring.apply(ctx);
287             }
288         }
289     }
290 }
291
Popular Tags