1 19 package org.netbeans.modules.gsf.browser; 20 21 import java.awt.Color ; 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.beans.PropertyChangeSupport ; 25 import java.util.Iterator ; 26 import java.util.Set ; 27 28 import javax.swing.SwingUtilities ; 29 import javax.swing.text.BadLocationException ; 30 import javax.swing.text.Document ; 31 import javax.swing.text.JTextComponent ; 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 54 public class HighlightSections { 55 private static final HighlightSections DEFAULT = new HighlightSections(); 56 private final Set <EditorUI> INSTALLED = new WeakSet<EditorUI>(); 57 private ParserResult.AstTreeNode selectedNode; 58 private Document 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 getSelectedDocument() { 72 return selectedDocument; 73 } 74 75 public void setSelectedNode(Document selectedDocument, ParserResult.AstTreeNode selectedNode) { 76 this.selectedDocument = selectedDocument; 77 this.selectedNode = selectedNode; 78 } 79 80 public void install(final JTextComponent component) { 81 if (component == null) { 82 return; 84 } 85 86 Mutex.EVENT.readAccess(new Runnable () { 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 editorUI.repaint(0); 104 } 105 } 106 }); 107 } 108 109 public void uninstall() { 110 Mutex.EVENT.readAccess(new Runnable () { 111 public void run() { 112 for (Iterator i = INSTALLED.iterator(); i.hasNext();) { 113 EditorUI editorUI = (EditorUI)i.next(); 114 editorUI.removeLayer(Layer.NAME); 115 } 116 117 INSTALLED.clear(); 118 119 repaintMostActiveComponent(); 122 } 123 }); 124 } 125 126 public void setColor(final JTextComponent component, final Color color) { 127 Mutex.EVENT.readAccess(new Runnable () { 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 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 NAME = "browser-highlight-layer"; 166 private static final int VISIBILITY = 7990; 168 private final Color HIGHLIGHTING_COLOR = new Color (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 color) { 183 coloring = new Coloring(null, null, color); 184 } 185 186 public void colorChanged() { 187 coloring = null; 188 189 } 191 192 public void init(DrawContext ctx) { 193 if (!enabled) { 194 return; 195 } 196 197 BaseDocument doc = (BaseDocument)ctx.getEditorUI().getDocument(); 198 Document 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 } 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]) { 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 |