/*
* SyntaxView.java
*
* Created on December 17, 2006, 1:03 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package xmllexerapplication;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.Lexer;
import org.antlr.runtime.Token;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.HashMap;
import java.util.Map;
import javax.swing.text.Element;
import javax.swing.text.PlainView;
import javax.swing.text.Segment;
import javax.swing.text.StyleContext;
import javax.swing.text.Utilities;
/**
*
* @author Yves Zoundi
*/
public class SyntaxView extends PlainView {
private Segment line;
private Segment seg = new Segment();
private final Lexer lexer;
private Color defaultColor = Color.BLACK;
private Map styleMap = new HashMap();
// private SwingDocumentStream is;
public SyntaxView(Element elem) {
super(elem);
lexer = new JavaLexer();
line = new Segment();
this.styleMap = new ColorProvider().getStyles();
}
protected void drawLine(int lineIndex, Graphics g, int x, int y) {
Graphics2D g2d = (Graphics2D) g;
try {
Element lineElement = getElement()
.getElement(lineIndex);
int start = lineElement.getStartOffset();
int end = lineElement.getEndOffset();
getDocument().getText(start, end - (start + 1), line);
lexer.setCharStream(new ANTLRStringStream(line.toString()));
int last = start;
int realStart;
int thisStart;
boolean gotMatch = false;
Token token = null;
while ((token = lexer.nextToken()) != Token.EOF_TOKEN) {
int val = token.getType();
gotMatch = true;
realStart = token.getCharPositionInLine() + start;
/* color any text after last and before realStart with default color */
if (last < realStart) {
g2d.setColor(defaultColor);
g2d.setFont(g2d.getFont().deriveFont(Font.PLAIN));
getDocument().getText(last, Math.abs(realStart - last), seg);
x = Utilities.drawTabbedText(seg, x, y, g2d, this, 0);
}
setFont(g2d, val);
/* get segement of text for lexer match */
getDocument().getText(realStart, token.getText().length(), seg);
thisStart = x;
x = Utilities.drawTabbedText(seg, x, y, g2d, this, 0);
last = realStart + token.getText().length();
}
g2d.setColor(defaultColor);
g2d.setFont(g2d.getFont().deriveFont(Font.PLAIN));
if ((last < end) && gotMatch) {
// draw text from end of last match to end of segment
getDocument().getText(last, end - last, seg);
x = Utilities.drawTabbedText(seg, x, y, g2d, this, 0);
} else if (!gotMatch) {
//no match - draw whole segment
Utilities.drawTabbedText(line, x, y, g2d, this, 0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void setFont(Graphics2D g2d, int val) {
g2d.setFont(g2d.getFont().deriveFont(Font.PLAIN));
if (styleMap.containsKey(new Integer(val))) {
StyleInfo style = (StyleInfo) styleMap.get(new Integer(val));
g2d.setColor(style.color);
if (style.bold && style.italic) {
g2d.setFont(g2d.getFont().deriveFont(Font.BOLD | Font.ITALIC));
} else if (style.bold) {
g2d.setFont(g2d.getFont().deriveFont(Font.BOLD));
} else if (style.italic) {
g2d.setFont(g2d.getFont().deriveFont(Font.ITALIC));
}
} else {
// System.err.println("KEY NOT IN MAP " + val);
g2d.setColor(defaultColor);
}
}
}