1 9 package bluej.editor.moe; 10 11 16 17 import javax.swing.text.*; 18 19 import java.awt.*; 20 import org.syntax.jedit.tokenmarker.*; 21 import org.syntax.jedit.*; 22 23 36 37 public abstract class BlueJSyntaxView extends PlainView 38 { 39 40 public static final short TAG_WIDTH = 14; 41 protected static final int BREAKPOINT_OFFSET = TAG_WIDTH + 2; 42 43 private Segment line; 45 46 private Font defaultFont; 47 private Font lineNumberFont; 49 private Font smallLineNumberFont; 50 FontMetrics lineNumberMetrics; 51 private boolean initialised = false; 52 53 57 public BlueJSyntaxView(Element elem) 58 { 59 super(elem); 60 line = new Segment(); 61 } 62 63 88 protected void drawLine(int lineIndex, Graphics g, int x, int y) 89 { 90 if(!initialised) 91 initialise(g); 92 93 SyntaxDocument document = (SyntaxDocument)getDocument(); 94 TokenMarker tokenMarker = document.getTokenMarker(); 95 96 Color def = getDefaultColor(); 97 98 try { 99 Element lineElement = getElement().getElement(lineIndex); 100 int start = lineElement.getStartOffset(); 101 int end = lineElement.getEndOffset(); 102 103 document.getText(start, end - (start + 1), line); 104 g.setColor(def); 105 106 paintTaggedLine(line, lineIndex, g, x, y, document, tokenMarker, def, lineElement); 107 } 108 catch(BadLocationException bl) { 109 bl.printStackTrace(); 111 } 112 } 113 114 117 public abstract void paintTaggedLine(Segment line, int lineIndex, Graphics g, int x, int y, 118 SyntaxDocument document, TokenMarker tokenMarker, Color def, Element lineElement); 119 120 123 protected void drawLineNumber(Graphics g, int lineNumber, int x, int y) 124 { 125 g.setColor(Color.darkGray); 126 127 String number = Integer.toString(lineNumber); 128 int stringWidth = lineNumberMetrics.stringWidth(number); 129 int xoffset = BREAKPOINT_OFFSET - stringWidth - 4; 130 131 if(xoffset < -2) xoffset++; 133 134 if(xoffset < -2) { g.setFont(smallLineNumberFont); 136 g.drawString(number, x-3, y); 137 } 138 else { 139 g.setFont(lineNumberFont); 140 g.drawString(number, x + xoffset, y); 141 } 142 g.setFont(defaultFont); 143 } 144 145 150 protected void paintSyntaxLine(Segment line, int lineIndex, int x, int y, 151 Graphics g, SyntaxDocument document, 152 TokenMarker tokenMarker, Color def) 153 { 154 Color[] colors = document.getColors(); 155 Token tokens = tokenMarker.markTokens(line, lineIndex); 156 int offset = 0; 157 for(;;) { 158 byte id = tokens.id; 159 if(id == Token.END) 160 break; 161 162 int length = tokens.length; 163 Color color; 164 if(id == Token.NULL) 165 color = def; 166 else { 167 if(id < colors.length) 170 color = colors[id]; 171 else color = def; 172 } 173 g.setColor(color == null ? def : color); 174 175 line.count = length; 176 x = Utilities.drawTabbedText(line,x,y,g,this,offset); 177 line.offset += length; 178 offset += length; 179 180 tokens = tokens.next; 181 } 182 } 183 184 185 191 protected final boolean hasTag(Element line, String tag) 192 { 193 return Boolean.TRUE.equals(line.getAttributes().getAttribute(tag)); 194 } 195 196 197 200 private void initialise(Graphics g) 201 { 202 defaultFont = g.getFont(); 203 lineNumberFont = defaultFont.deriveFont(9.0f); 204 smallLineNumberFont = defaultFont.deriveFont(7.0f); 205 Component c = getContainer(); 206 lineNumberMetrics = c.getFontMetrics(lineNumberFont); 207 initialised = true; 208 } 209 210 213 protected Color getDefaultColor() 214 { 215 return getContainer().getForeground(); 216 } 217 218 231 public Shape modelToView(int pos, Shape a, Position.Bias b) 232 throws BadLocationException 233 { 234 Document doc = getDocument(); 236 Element map = getElement(); 237 int lineIndex = map.getElementIndex(pos); 238 Rectangle lineArea = lineToRect(a, lineIndex); 239 240 int tabBase = lineArea.x + TAG_WIDTH + 2; 242 243 Element line = map.getElement(lineIndex); 244 int p0 = line.getStartOffset(); 245 Segment buffer = getLineBuffer(); 246 doc.getText(p0, pos - p0, buffer); 247 int xOffs = Utilities.getTabbedTextWidth(buffer, metrics, tabBase, this, p0); 248 249 lineArea.x += xOffs + (TAG_WIDTH + 2); 251 lineArea.width = 1; 252 lineArea.height = metrics.getHeight(); 253 return lineArea; 254 } 255 256 257 268 public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) 269 { 270 bias[0] = Position.Bias.Forward; 271 272 Rectangle alloc = a.getBounds(); 273 Document doc = getDocument(); 274 int x = (int) fx; 275 int y = (int) fy; 276 if (y < alloc.y) { 277 return getStartOffset(); 280 } else if (y > alloc.y + alloc.height) { 281 return getEndOffset() - 1; 284 } else { 285 Element map = doc.getDefaultRootElement(); 291 int lineIndex = Math.abs((y - alloc.y) / metrics.getHeight() ); 292 if (lineIndex >= map.getElementCount()) { 293 return getEndOffset() - 1; 294 } 295 Element line = map.getElement(lineIndex); 296 if (x < alloc.x) { 297 return line.getStartOffset(); 299 } else if (x > alloc.x + alloc.width) { 300 return line.getEndOffset() - 1; 302 } else { 303 try { 305 Segment buffer = getLineBuffer(); 306 int p0 = line.getStartOffset(); 307 int p1 = line.getEndOffset() - 1; 308 doc.getText(p0, p1 - p0, buffer); 309 int tabBase = alloc.x + TAG_WIDTH + 2; 311 int offs = p0 + Utilities.getTabbedTextOffset(buffer, metrics, 312 tabBase, x, this, p0); 313 return offs; 314 } catch (BadLocationException e) { 315 return -1; 317 } 318 } 319 } 320 } 321 322 323 325 335 public float nextTabStop(float x, int tabOffset) { 336 int tabSize = getTabSize() * metrics.charWidth('m'); 338 if (tabSize == 0) { 339 return x; 340 } 341 int tabStopNumber = (int)((x - BREAKPOINT_OFFSET) / tabSize) + 1; 342 return (tabStopNumber * tabSize) + BREAKPOINT_OFFSET + 2; 343 } 344 345 346 350 public Rectangle lineToRect(Shape a, int line) { 351 Rectangle r = null; 352 if (metrics != null) { 353 Rectangle alloc = a.getBounds(); 354 r = new Rectangle(alloc.x, alloc.y + (line * metrics.getHeight()), 355 alloc.width, metrics.getHeight()); 356 } 357 return r; 358 } 359 } 360 | Popular Tags |