/******************************************************************************* * Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html * * Contributors: * Mathew A. Nelson * - Initial API and implementation * Flemming N. Larsen * - Added syntax highlightning for annotations *******************************************************************************/ package net.sf.robocode.ui.editor; import javax.swing.event.DocumentEvent; import javax.swing.text.*; import java.awt.*; /** * @author Mathew A. Nelson (original) * @author Flemming N. Larsen (contributor) */ public class RobocodeView extends PlainView { public final static Color commentColor = new Color(0, 150, 0); public final static Color stringColor = new Color(0, 150, 150); public final static Color keywordColor = new Color(0, 0, 150); public final static Color annotationColor = new Color(150, 0, 150); public final static Color textColor = Color.black; public final static int TEXT = 0; public final static int KEYWORD = 1; public final static int COMMENT = 2; public final static int STRING = 3; public final static int MULTILINECOMMENT = 4; public final static int ANNOTATION = 5; public RobocodeView(Element elem) { super(elem); } @Override public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) { super.changedUpdate(e, a, f); JavaDocument d = (JavaDocument) e.getDocument(); if (d.isNeedsRedraw()) { getContainer().repaint(); d.setNeedsRedraw(false); } } @Override protected int drawUnselectedText(java.awt.Graphics g, int x, int y, int p0, int p1) throws BadLocationException { Document doc = getDocument(); Segment segment = new Segment(); Segment token = getLineBuffer(); doc.getText(p0, p1 - p0, segment); int count = p1 - p0; int left = 0; int state = TEXT; int elementIndex = doc.getDefaultRootElement().getElementIndex(p0); AttributeSet lineAttributes = doc.getDefaultRootElement().getElement(elementIndex).getAttributes(); if (lineAttributes.isDefined("inComment")) { state = MULTILINECOMMENT; } for (int i = 0; i < count; i++) { // Starting in default text state. if (state == TEXT) { if (Character.isLetter(segment.array[i + segment.offset]) && Character.isLowerCase(segment.array[i + segment.offset])) { // flush now g.setColor(textColor); doc.getText(p0 + left, i - left, token); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i; state = KEYWORD; } // Do nothing else if (segment.array[i + segment.offset] == '/') { // flush now g.setColor(textColor); doc.getText(p0 + left, i - left, token); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i; state = COMMENT; } else if (segment.array[i + segment.offset] == '"') { // flush now g.setColor(textColor); doc.getText(p0 + left, i - left, token); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i; state = STRING; } else if (segment.array[i + segment.offset] == '@') { // flush now g.setColor(textColor); doc.getText(p0 + left, i - left, token); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i; state = ANNOTATION; } } else if (state == KEYWORD) { // Still if (Character.isLetter(segment.array[i + segment.offset])) {// && Character.isLowerCase(segment.array[i+segment.offset])) } else { // flush now doc.getText(p0 + left, i - left, token); if (Keywords.isKeyword(token)) { g.setColor(keywordColor); } else { g.setColor(textColor); } x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i; state = TEXT; if (segment.array[i + segment.offset] == '/') { state = COMMENT; } else if (segment.array[i + segment.offset] == '"') { state = STRING; } } } else if (state == COMMENT) { if (segment.array[i + segment.offset] == '/') { break; } else if (segment.array[i + segment.offset] == '*') { state = MULTILINECOMMENT; } else { state = TEXT; } } else if (state == MULTILINECOMMENT) { if (i > 0 && segment.array[i + segment.offset] == '/' && segment.array[i + segment.offset - 1] == '*') { // flush now doc.getText(p0 + left, i + 1 - left, token); g.setColor(commentColor); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i + 1; state = TEXT; } } else if (state == STRING) { if (segment.array[i + segment.offset] == '"') { // flush now doc.getText(p0 + left, i + 1 - left, token); g.setColor(stringColor); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i + 1; state = TEXT; } } else if (state == ANNOTATION) { if (!Character.isJavaIdentifierPart(segment.array[i + segment.offset + 1])) { // flush now doc.getText(p0 + left, i + 1 - left, token); g.setColor(annotationColor); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i + 1; state = TEXT; } } // Starting not in token } // end loop // Flush last doc.getText(p0 + left, p1 - p0 - left, token); if (state == KEYWORD) { if (Keywords.isKeyword(token)) { g.setColor(keywordColor); } else { g.setColor(textColor); } } else if (state == STRING) { g.setColor(stringColor); } else if (state == COMMENT && ((p1 - p0 - left) > 1)) { g.setColor(commentColor); } else if (state == MULTILINECOMMENT) { g.setColor(commentColor); } else if (state == ANNOTATION) { g.setColor(annotationColor); } else { g.setColor(textColor); } x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); return x; } @Override protected int getTabSize() { return 4; } @Override public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) { super.insertUpdate(e, a, f); JavaDocument d = (JavaDocument) e.getDocument(); if (d.isNeedsRedraw()) { getContainer().repaint(); d.setNeedsRedraw(false); } } @Override public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) { super.removeUpdate(e, a, f); JavaDocument d = (JavaDocument) e.getDocument(); if (d.isNeedsRedraw()) { getContainer().repaint(); d.setNeedsRedraw(false); } } }