1 19 20 package org.netbeans.editor.ext; 21 22 import java.awt.Rectangle ; 23 import java.awt.Font ; 24 import java.awt.event.MouseEvent ; 25 import java.awt.event.ActionListener ; 26 import java.awt.event.ActionEvent ; 27 import javax.swing.SwingUtilities ; 28 import javax.swing.Timer ; 29 import javax.swing.text.JTextComponent ; 30 import javax.swing.text.BadLocationException ; 31 import org.netbeans.editor.BaseCaret; 32 import org.netbeans.editor.Coloring; 33 import org.netbeans.editor.EditorUI; 34 import org.netbeans.editor.MarkFactory; 35 import org.netbeans.editor.DrawLayerFactory; 36 import org.netbeans.editor.Utilities; 37 import org.netbeans.editor.BaseDocument; 38 import org.netbeans.editor.BaseTextUI; 39 import org.netbeans.editor.InvalidMarkException; 40 import org.netbeans.editor.DrawContext; 41 import org.netbeans.editor.DrawLayer; 42 import org.netbeans.editor.SettingsUtil; 43 import org.netbeans.editor.SettingsChangeEvent; 44 import org.netbeans.editor.SettingsNames; 45 import org.netbeans.editor.WeakTimerListener; 46 47 53 54 public class ExtCaret extends BaseCaret { 55 56 65 public static final String HIGHLIGHT_ROW_LAYER_NAME = "highlight-row-layer"; 67 76 public static final int HIGHLIGHT_ROW_LAYER_VISIBILITY = 2050; 77 78 79 public static final String HIGHLIGHT_BRACE_LAYER_NAME = "highlight-brace-layer"; 81 82 public static final int HIGHLIGHT_BRACE_LAYER_VISIBILITY = 11000; 83 84 85 boolean highlightBrace; 86 87 88 Coloring highlightBraceColoring; 89 90 91 MarkFactory.DrawMark highlightBraceStartMark; 92 93 94 MarkFactory.DrawMark highlightBraceEndMark; 95 96 97 private Timer braceTimer; 98 private ActionListener braceTimerListener; 100 104 private boolean matchBraceUpdateSync; 105 106 109 boolean braceMarksValid; 110 111 boolean simpleMatchBrace; 112 113 private boolean popupMenuEnabled; 114 115 static final long serialVersionUID =-4292670043122577690L; 116 117 118 protected void modelChanged(BaseDocument oldDoc, BaseDocument newDoc) { 119 braceMarksValid = false; if (highlightBraceStartMark != null) { 122 try { 123 highlightBraceStartMark.remove(); 124 } catch (InvalidMarkException e) { 125 } 126 highlightBraceStartMark = null; 127 } 128 129 if (highlightBraceEndMark != null) { 130 try { 131 highlightBraceEndMark.remove(); 132 } catch (InvalidMarkException e) { 133 } 134 highlightBraceEndMark = null; 135 } 136 137 super.modelChanged( oldDoc, newDoc ); 138 } 139 140 143 public void settingsChange(SettingsChangeEvent evt) { 144 super.settingsChange(evt); 145 JTextComponent c = component; 146 if (c != null) { 147 148 EditorUI editorUI = Utilities.getEditorUI(c); 149 Class kitClass = Utilities.getKitClass(c); 150 highlightBraceColoring = editorUI.getColoring( 151 ExtSettingsNames.HIGHLIGHT_MATCH_BRACE_COLORING); 152 153 highlightBrace = SettingsUtil.getBoolean(kitClass, 154 ExtSettingsNames.HIGHLIGHT_MATCH_BRACE, 155 ExtSettingsDefaults.defaultHighlightMatchBrace); 156 int highlightBraceDelay = SettingsUtil.getInteger(kitClass, 157 ExtSettingsNames.HIGHLIGHT_MATCH_BRACE_DELAY, 158 ExtSettingsDefaults.defaultHighlightMatchBraceDelay); 159 160 if (highlightBrace) { 161 if (highlightBraceDelay > 0) { 162 final JTextComponent c2 = component; 164 165 braceTimer = new Timer (highlightBraceDelay, null); 166 braceTimerListener = 167 new ActionListener () { 168 public void actionPerformed(ActionEvent evt2) { 169 SwingUtilities.invokeLater( 170 new Runnable () { 171 public void run() { 172 if (c2 != null) { 173 BaseDocument doc = Utilities.getDocument(c2); 174 if( doc != null ) { 175 doc.readLock(); 176 try { 177 updateMatchBrace(); 178 } finally { 179 doc.readUnlock(); 180 } 181 } 182 } 183 } 184 } 185 ); 186 } 187 }; 188 189 braceTimer.addActionListener(new WeakTimerListener(braceTimerListener)); 190 braceTimer.setRepeats(false); 191 } else { 192 braceTimer = null; } 194 c.repaint(); 195 } 196 197 simpleMatchBrace = SettingsUtil.getBoolean(kitClass, 198 ExtSettingsNames.CARET_SIMPLE_MATCH_BRACE, 199 ExtSettingsDefaults.defaultCaretSimpleMatchBrace); 200 201 popupMenuEnabled = SettingsUtil.getBoolean(kitClass, 202 ExtSettingsNames.POPUP_MENU_ENABLED, true); 203 } 204 } 205 206 public void install(JTextComponent c) { 207 EditorUI editorUI = Utilities.getEditorUI(c); 208 editorUI.addLayer(new HighlightBraceLayer(), HIGHLIGHT_BRACE_LAYER_VISIBILITY); 209 super.install(c); 210 } 211 212 public void deinstall(JTextComponent c) { 213 EditorUI editorUI = Utilities.getEditorUI(c); 214 editorUI.removeLayer(HIGHLIGHT_BRACE_LAYER_NAME); 215 super.deinstall(c); 216 } 217 218 221 protected void updateMatchBrace() { 222 JTextComponent c = component; 223 if (c != null && highlightBrace) { 224 try { 225 EditorUI editorUI = Utilities.getEditorUI(c); 226 BaseDocument doc = (BaseDocument)c.getDocument(); 227 int dotPos = getDot(); 228 boolean madeValid = false; if (dotPos > 0) { 230 int[] matchBlk = ((ExtSyntaxSupport)doc.getSyntaxSupport()) 231 .findMatchingBlock(dotPos - 1, simpleMatchBrace); 232 if (matchBlk != null) { 233 if (highlightBraceStartMark != null) { 234 int markStartPos = highlightBraceStartMark.getOffset(); 235 int markEndPos = highlightBraceEndMark.getOffset(); 236 if (markStartPos != matchBlk[0] || markEndPos != matchBlk[1]) { 237 editorUI.repaintBlock(markStartPos, markEndPos); 238 Utilities.moveMark(doc, highlightBraceStartMark, matchBlk[0]); 239 Utilities.moveMark(doc, highlightBraceEndMark, matchBlk[1]); 240 editorUI.repaintBlock(matchBlk[0], matchBlk[1]); 241 } else { if (!braceMarksValid) { editorUI.repaintBlock(matchBlk[0], matchBlk[1]); 244 } 245 } 246 } else { highlightBraceStartMark = new MarkFactory.DrawMark( 248 HIGHLIGHT_BRACE_LAYER_NAME, editorUI); 249 highlightBraceEndMark = new MarkFactory.DrawMark( 250 HIGHLIGHT_BRACE_LAYER_NAME, editorUI); 251 highlightBraceStartMark.setActivateLayer(true); 252 Utilities.insertMark(doc, highlightBraceStartMark, matchBlk[0]); 253 Utilities.insertMark(doc, highlightBraceEndMark, matchBlk[1]); 254 editorUI.repaintBlock(matchBlk[0], matchBlk[1]); 255 } 256 braceMarksValid = true; 257 madeValid = true; 258 } 259 } 260 261 if (!madeValid) { 262 if (braceMarksValid) { 263 braceMarksValid = false; 264 editorUI.repaintBlock(highlightBraceStartMark.getOffset(), 265 highlightBraceEndMark.getOffset()); 266 } 267 } 268 } catch (BadLocationException e) { 269 Utilities.annotateLoggable(e); 270 highlightBrace = false; 271 } catch (InvalidMarkException e) { 272 Utilities.annotateLoggable(e); 273 highlightBrace = false; 274 } 275 } 276 } 277 278 protected void update(boolean scrollViewToCaret) { 279 if (highlightBrace) { 280 if (matchBraceUpdateSync || braceTimer == null) { 281 updateMatchBrace(); 282 matchBraceUpdateSync = false; 283 284 } else { braceTimer.restart(); 286 } 287 } 288 289 super.update(scrollViewToCaret); 290 } 291 292 297 public void requestMatchBraceUpdateSync() { 298 matchBraceUpdateSync = true; 299 } 300 301 public void mousePressed(MouseEvent evt) { 302 Completion completion = ExtUtilities.getCompletion(component); 303 if (completion != null && completion.isPaneVisible()) { 304 completion.setPaneVisible(false); 306 } 307 super.mousePressed(evt); 308 showPopup(evt); 309 } 310 311 private boolean showPopup (MouseEvent evt) { 312 if (component != null && evt.isPopupTrigger() && popupMenuEnabled) { 314 ExtUtilities.getExtEditorUI(component).showPopupMenu(evt.getX(), evt.getY()); 315 return true; 316 } 317 return false; 318 } 319 320 public void mouseReleased(MouseEvent evt) { 321 if (!showPopup(evt)) { 322 super.mouseReleased(evt); 323 } 324 } 325 326 331 class HighlightBraceLayer extends DrawLayer.AbstractLayer { 332 333 public HighlightBraceLayer() { 334 super(HIGHLIGHT_BRACE_LAYER_NAME); 335 } 336 337 public void init(DrawContext ctx) { 338 } 339 340 public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) { 341 if (braceMarksValid) { 342 if (mark != null) 343 return mark.getActivateLayer(); 344 try { 345 if (ctx.getStartOffset() > highlightBraceEndMark.getOffset()) 346 return highlightBraceEndMark.getActivateLayer(); 347 if (ctx.getStartOffset() > highlightBraceStartMark.getOffset()) 348 return highlightBraceStartMark.getActivateLayer(); 349 } catch (InvalidMarkException ex) { 350 } 351 } 352 353 return false; 354 } 355 356 public void updateContext(DrawContext ctx) { 357 if (highlightBraceColoring != null) { 358 highlightBraceColoring.apply(ctx); 359 } 360 } 361 362 } 363 364 } 365 | Popular Tags |