1 33 34 package edu.rice.cs.drjava.model.definitions; 35 36 import javax.swing.text.*; 37 import java.awt.*; 38 import javax.swing.event.DocumentEvent ; 39 import java.util.Vector ; 41 42 import edu.rice.cs.drjava.DrJava; 43 import edu.rice.cs.drjava.model.*; 44 import edu.rice.cs.drjava.model.repl.InteractionsDJDocument; 45 import edu.rice.cs.drjava.config.OptionConstants; 46 import edu.rice.cs.drjava.config.OptionEvent; 47 import edu.rice.cs.drjava.config.OptionListener; 48 import edu.rice.cs.drjava.model.definitions.reducedmodel.*; 49 50 51 public class ColoringGlyphPainter extends GlyphView.GlyphPainter implements OptionConstants { 52 53 public static Color COMMENTED_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_COMMENT_COLOR); 54 public static Color DOUBLE_QUOTED_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_DOUBLE_QUOTED_COLOR); 55 public static Color SINGLE_QUOTED_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_SINGLE_QUOTED_COLOR); 56 public static Color NORMAL_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_NORMAL_COLOR); 57 public static Color KEYWORD_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_KEYWORD_COLOR); 58 public static Color NUMBER_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_NUMBER_COLOR); 59 public static Color TYPE_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_TYPE_COLOR); 60 public static Font MAIN_FONT = DrJava.getConfig().getSetting(FONT_MAIN); 61 62 public static Color INTERACTIONS_SYSTEM_ERR_COLOR = DrJava.getConfig().getSetting(SYSTEM_ERR_COLOR); 64 public static Color INTERACTIONS_SYSTEM_IN_COLOR = DrJava.getConfig().getSetting(SYSTEM_IN_COLOR); 65 public static Color INTERACTIONS_SYSTEM_OUT_COLOR = DrJava.getConfig().getSetting(SYSTEM_OUT_COLOR); 66 public static Color ERROR_COLOR = DrJava.getConfig().getSetting(INTERACTIONS_ERROR_COLOR); 68 public static Color DEBUGGER_COLOR = DrJava.getConfig().getSetting(DEBUG_MESSAGE_COLOR); 69 70 private boolean _listenersAttached; 71 private Runnable _lambdaRepaint; 72 private FontMetrics _metrics; 73 74 public ColoringGlyphPainter(Runnable lambdaRepaint) { 75 _listenersAttached = false; 76 _lambdaRepaint = lambdaRepaint; 77 } 79 80 81 public void paint(GlyphView v, Graphics g, Shape a, int start, int end) { 82 83 if (start == end) return; 86 87 sync(v); 88 89 Document doc = v.getDocument(); 92 AbstractDJDocument djdoc = null; 93 if (doc instanceof AbstractDJDocument) 94 djdoc = (AbstractDJDocument) doc; 95 else 96 return; 98 Segment text; 99 TabExpander expander = v.getTabExpander(); 100 Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds(); 101 102 int x = alloc.x; 104 int p = v.getStartOffset(); 105 if (p != start) { 106 text = v.getText(p, start); 107 int width = Utilities.getTabbedTextWidth(text, _metrics, x, expander, p); 108 x += width; 109 } 110 111 int y = alloc.y + _metrics.getHeight() - _metrics.getDescent(); 113 114 text = v.getText(start, end); 115 116 Vector <HighlightStatus> stats = djdoc.getHighlightStatus(start, end); 117 if (stats.size() < 1) throw new RuntimeException ("GetHighlightStatus returned nothing!"); 118 try { 119 for (int i = 0; i < stats.size(); i++) { 120 HighlightStatus stat = stats.get(i); 121 int length = stat.getLength(); 122 int location = stat.getLocation(); 123 124 125 if((location < end) && ((location + length) > start)) { 126 127 if (location < start) { 130 length -= (start-location); 131 location = start; 132 } 133 if ((location + length) > end) { 134 length = end - location; 135 } 136 137 if (!(djdoc instanceof InteractionsDJDocument) || !((InteractionsDJDocument)djdoc).setColoring((start+end)/2,g)) 138 setFormattingForState(g, stat.getState()); 139 140 djdoc.getText(location, length, text); 141 x = Utilities.drawTabbedText(text, x, y, g, v.getTabExpander(), location); 142 } 143 } 144 } 145 catch(BadLocationException ble) { 146 } 148 } 149 150 154 public float getSpan(GlyphView v, int start, int end, 155 TabExpander e, float x) { 156 sync(v); 157 Segment text = v.getText(start, end); 158 int width = Utilities.getTabbedTextWidth(text, _metrics, (int) x, e, start); 159 return width; 160 } 161 162 public float getHeight(GlyphView v) { 163 sync(v); 164 return _metrics.getHeight(); 165 } 166 167 171 public float getAscent(GlyphView v) { 172 sync(v); 173 return _metrics.getAscent(); 174 } 175 176 180 public float getDescent(GlyphView v) { 181 sync(v); 182 return _metrics.getDescent(); 183 } 184 185 public Shape modelToView(GlyphView v, int pos, Position.Bias bias, 186 Shape a) throws BadLocationException { 187 188 sync(v); 189 Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds(); 190 int start = v.getStartOffset(); 191 int end = v.getEndOffset(); 192 TabExpander expander = v.getTabExpander(); 193 Segment text; 194 195 if(pos == end) { 196 return new Rectangle(alloc.x + alloc.width, alloc.y, 0, 199 _metrics.getHeight()); 200 } 201 if ((pos >= start) && (pos <= end)) { 202 text = v.getText(start, pos); 204 int width = Utilities.getTabbedTextWidth(text, _metrics, alloc.x, expander, start); 205 return new Rectangle(alloc.x + width, alloc.y, 0, _metrics.getHeight()); 206 } 207 throw new BadLocationException("modelToView - can't convert", end); 208 } 209 210 224 public int viewToModel(GlyphView v, float x, float y, Shape a, 225 Position.Bias[] biasReturn) { 226 sync(v); 227 Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds(); 228 int start = v.getStartOffset(); 229 int end = v.getEndOffset(); 230 TabExpander expander = v.getTabExpander(); 231 Segment text = v.getText(start, end); 232 233 int offs = Utilities.getTabbedTextOffset(text, _metrics, 234 alloc.x, (int) x, expander, start); 235 int retValue = start + offs; 236 if(retValue == end) { 237 retValue--; 240 } 241 biasReturn[0] = Position.Bias.Forward; 242 return retValue; 243 } 244 245 257 public int getBoundedPosition(GlyphView v, int start, float x, float len) { 258 sync(v); 259 TabExpander expander = v.getTabExpander(); 260 Segment s = v.getText(start, v.getEndOffset()); 261 int index = Utilities.getTabbedTextOffset(s, _metrics, (int)x, (int)(x+len), 262 expander, start, false); 263 int end = start + index; 264 return end; 265 } 266 267 void sync(GlyphView v) { 268 Font f = v.getFont(); 269 if ((_metrics == null) || (! f.equals(_metrics.getFont()))) { 270 Toolkit kit; 272 Component c = v.getContainer(); 273 if (c != null) { 274 kit = c.getToolkit(); 275 } else { 276 kit = Toolkit.getDefaultToolkit(); 277 } 278 284 @SuppressWarnings ("deprecation") FontMetrics newMetrics = kit.getFontMetrics(f); 285 _metrics = newMetrics; 286 } 287 288 Document doc = v.getDocument(); 289 if (!_listenersAttached && (doc instanceof AbstractDJDocument)) { 290 attachOptionListeners((AbstractDJDocument)doc); 291 } 292 } 293 294 298 private void setFormattingForState(Graphics g, int state) { 299 switch (state) { 300 case HighlightStatus.NORMAL: 301 g.setColor(NORMAL_COLOR); 302 break; 303 case HighlightStatus.COMMENTED: 304 g.setColor(COMMENTED_COLOR); 305 break; 306 case HighlightStatus.SINGLE_QUOTED: 307 g.setColor(SINGLE_QUOTED_COLOR); 308 break; 309 case HighlightStatus.DOUBLE_QUOTED: 310 g.setColor(DOUBLE_QUOTED_COLOR); 311 break; 312 case HighlightStatus.KEYWORD: 313 g.setColor(KEYWORD_COLOR); 314 break; 315 case HighlightStatus.NUMBER: 316 g.setColor(NUMBER_COLOR); 317 break; 318 case HighlightStatus.TYPE: 319 g.setColor(TYPE_COLOR); 320 break; 321 default: 322 throw new RuntimeException ("Can't get color for invalid state: " + state); 323 } 324 g.setFont(MAIN_FONT); 325 } 326 327 328 333 340 private void attachOptionListeners(AbstractDJDocument doc) { 341 final ColorOptionListener col = new ColorOptionListener(); 343 final FontOptionListener fol = new FontOptionListener(); 344 345 DrJava.getConfig().addOptionListener( OptionConstants.DEFINITIONS_COMMENT_COLOR, col); 348 DrJava.getConfig().addOptionListener( OptionConstants.DEFINITIONS_DOUBLE_QUOTED_COLOR, col); 349 DrJava.getConfig().addOptionListener( OptionConstants.DEFINITIONS_SINGLE_QUOTED_COLOR, col); 350 DrJava.getConfig().addOptionListener( OptionConstants.DEFINITIONS_NORMAL_COLOR, col); 351 DrJava.getConfig().addOptionListener( OptionConstants.DEFINITIONS_KEYWORD_COLOR, col); 352 DrJava.getConfig().addOptionListener( OptionConstants.DEFINITIONS_NUMBER_COLOR, col); 353 DrJava.getConfig().addOptionListener( OptionConstants.DEFINITIONS_TYPE_COLOR, col); 354 DrJava.getConfig().addOptionListener( OptionConstants.FONT_MAIN, fol); 355 356 DrJava.getConfig().addOptionListener( OptionConstants.SYSTEM_ERR_COLOR, col); 357 DrJava.getConfig().addOptionListener( OptionConstants.SYSTEM_IN_COLOR, col); 358 DrJava.getConfig().addOptionListener( OptionConstants.SYSTEM_OUT_COLOR, col); 359 DrJava.getConfig().addOptionListener( OptionConstants.INTERACTIONS_ERROR_COLOR, col); 360 DrJava.getConfig().addOptionListener( OptionConstants.DEBUG_MESSAGE_COLOR, col); 361 362 if (doc instanceof DefinitionsDocument) { 367 ((DefinitionsDocument)doc).addDocumentClosedListener(new DocumentClosedListener() { 369 public void close() { 370 DrJava.getConfig().removeOptionListener( OptionConstants.DEFINITIONS_COMMENT_COLOR, col); 371 DrJava.getConfig().removeOptionListener( OptionConstants.DEFINITIONS_DOUBLE_QUOTED_COLOR, col); 372 DrJava.getConfig().removeOptionListener( OptionConstants.DEFINITIONS_SINGLE_QUOTED_COLOR, col); 373 DrJava.getConfig().removeOptionListener( OptionConstants.DEFINITIONS_NORMAL_COLOR, col); 374 DrJava.getConfig().removeOptionListener( OptionConstants.DEFINITIONS_KEYWORD_COLOR, col); 375 DrJava.getConfig().removeOptionListener( OptionConstants.DEFINITIONS_NUMBER_COLOR, col); 376 DrJava.getConfig().removeOptionListener( OptionConstants.DEFINITIONS_TYPE_COLOR, col); 377 DrJava.getConfig().removeOptionListener( OptionConstants.FONT_MAIN, fol); 378 DrJava.getConfig().removeOptionListener( OptionConstants.SYSTEM_ERR_COLOR, col); 379 DrJava.getConfig().removeOptionListener( OptionConstants.SYSTEM_IN_COLOR, col); 380 DrJava.getConfig().removeOptionListener( OptionConstants.SYSTEM_OUT_COLOR, col); 381 DrJava.getConfig().removeOptionListener( OptionConstants.INTERACTIONS_ERROR_COLOR, col); 382 DrJava.getConfig().removeOptionListener( OptionConstants.DEBUG_MESSAGE_COLOR, col); 383 } 384 }); 385 } 386 _listenersAttached = true; 387 } 388 389 390 public void updateColors() { 391 392 COMMENTED_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_COMMENT_COLOR); 393 DOUBLE_QUOTED_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_DOUBLE_QUOTED_COLOR); 394 SINGLE_QUOTED_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_SINGLE_QUOTED_COLOR); 395 NORMAL_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_NORMAL_COLOR); 396 KEYWORD_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_KEYWORD_COLOR); 397 NUMBER_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_NUMBER_COLOR); 398 TYPE_COLOR = DrJava.getConfig().getSetting(DEFINITIONS_TYPE_COLOR); 399 400 INTERACTIONS_SYSTEM_ERR_COLOR = DrJava.getConfig().getSetting(SYSTEM_ERR_COLOR); 401 INTERACTIONS_SYSTEM_IN_COLOR = DrJava.getConfig().getSetting(SYSTEM_IN_COLOR); 402 INTERACTIONS_SYSTEM_OUT_COLOR = DrJava.getConfig().getSetting(SYSTEM_OUT_COLOR); 403 ERROR_COLOR = DrJava.getConfig().getSetting(INTERACTIONS_ERROR_COLOR); 404 DEBUGGER_COLOR = DrJava.getConfig().getSetting(DEBUG_MESSAGE_COLOR); 405 406 edu.rice.cs.util.swing.Utilities.invokeLater(_lambdaRepaint); 407 } 408 409 410 private class ColorOptionListener implements OptionListener<Color> { 411 public void optionChanged(OptionEvent<Color> oce) { updateColors(); } 412 } 413 414 private static class FontOptionListener implements OptionListener<Font> { 415 public void optionChanged(OptionEvent<Font> oce) { 416 MAIN_FONT = DrJava.getConfig().getSetting(FONT_MAIN); 417 } 418 } 419 420 } 421 | Popular Tags |