Java tutorial
/* * $Id: HighlightPlainContext.java,v 1.3 2005/01/09 15:26:28 amunoz Exp $ * * Copyright (C) 2003 Antonio G. Muoz Conejo <amunoz@tomby.homelinux.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package tk.tomby.tedit.editorkits; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.PlainView; import javax.swing.text.Segment; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import javax.swing.text.Utilities; import javax.swing.text.View; import javax.swing.text.ViewFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import tk.tomby.tedit.core.ICleanable; import tk.tomby.tedit.messages.IMessageListener; import tk.tomby.tedit.messages.PreferenceMessage; import tk.tomby.tedit.services.MessageManager; import tk.tomby.tedit.services.PreferenceManager; import tk.tomby.tedit.syntax.Syntax; import tk.tomby.tedit.syntax.Tokenizer; /** * DOCUMENT ME! * * @author $Author: amunoz $ * @version $Revision: 1.3 $ */ public class HighlightPlainContext extends StyleContext implements ViewFactory, IMessageListener<PreferenceMessage>, ICleanable { //~ Static fields/initializers ***************************************************************** /** DOCUMENT ME! */ private static Log log = LogFactory.getLog(HighlightPlainContext.class); //~ Instance fields **************************************************************************** /** DOCUMENT ME! */ private Tokenizer tokenizer = null; //~ Constructors ******************************************************************************* /** * Creates a new HighlightContext object. * * @param syntax DOCUMENT ME! */ public HighlightPlainContext(Syntax syntax) { super(); tokenizer = new Tokenizer(syntax); Style style = addStyle(Syntax.UNKNOWN_NAME, getStyle(DEFAULT_STYLE)); int red = PreferenceManager.getInt("general.editor.foreground.red", 0); int green = PreferenceManager.getInt("general.editor.foreground.green", 0); int blue = PreferenceManager.getInt("general.editor.foreground.blue", 0); style.addAttribute(StyleConstants.Foreground, new Color(red, green, blue)); String font = PreferenceManager.getString("general.editor.font", "Monospaced"); int size = PreferenceManager.getInt("general.editor.fontSize", 12); style.addAttribute(StyleConstants.FontFamily, new Font(font, Font.PLAIN, size)); createStyle(Syntax.KEYWORD1_NAME, "highlight.keyword1"); createStyle(Syntax.KEYWORD2_NAME, "highlight.keyword2"); createStyle(Syntax.KEYWORD3_NAME, "highlight.keyword3"); createStyle(Syntax.KEYWORD4_NAME, "highlight.keyword4"); createStyle(Syntax.COMMENT1_NAME, "highlight.comment1"); createStyle(Syntax.COMMENT2_NAME, "highlight.comment2"); createStyle(Syntax.COMMENT3_NAME, "highlight.comment3"); createStyle(Syntax.COMMENT4_NAME, "highlight.comment3"); createStyle(Syntax.LITERAL1_NAME, "highlight.literal1"); createStyle(Syntax.LITERAL2_NAME, "highlight.literal2"); createStyle(Syntax.LITERAL3_NAME, "highlight.literal3"); createStyle(Syntax.LITERAL4_NAME, "highlight.literal4"); createStyle(Syntax.IDENTIFIER1_NAME, "highlight.identifier1"); createStyle(Syntax.IDENTIFIER2_NAME, "highlight.identifier2"); createStyle(Syntax.IDENTIFIER3_NAME, "highlight.identifier3"); createStyle(Syntax.IDENTIFIER4_NAME, "highlight.identifier4"); createStyle(Syntax.OPERATOR_NAME, "highlight.operator"); createStyle(Syntax.SEPARATOR_NAME, "highlight.separator"); createStyle(Syntax.LABEL_NAME, "highlight.label"); createStyle(Syntax.MARKUP_NAME, "highlight.markup"); createStyle(Syntax.DIGIT_NAME, "highlight.digit"); createStyle(Syntax.SCRIPTLET_NAME, "highlight.scriptlet"); MessageManager.addMessageListener(MessageManager.PREFERENCE_GROUP_NAME, this); } //~ Methods ************************************************************************************ /** * DOCUMENT ME! * * @param type * * @return */ public Style getTokenStyle(int type) { String styleName = Syntax.getTokenName(type); return getStyle(styleName); } /** * DOCUMENT ME! */ public void cleanup() { MessageManager.removeMessageListener(MessageManager.PREFERENCE_GROUP_NAME, this); } /** * DOCUMENT ME! * * @param element DOCUMENT ME! * * @return DOCUMENT ME! */ public View create(Element element) { if (log.isDebugEnabled()) { log.debug(element.getName()); } return new HighlightView(element); } /** * DOCUMENT ME! * * @param message DOCUMENT ME! */ public void receiveMessage(PreferenceMessage message) { if (message.getKey().startsWith("highlight")) { int index = message.getKey().indexOf('.'); String styleName = message.getKey().substring(index + 1); log.debug("styleName=" + styleName); HighlightModel model = (HighlightModel) message.getNewValue(); Style style = getStyle(styleName); style.addAttribute(StyleConstants.Foreground, model.getColor()); style.addAttribute(StyleConstants.FontFamily, model.getFont()); } } /** * DOCUMENT ME! * * @param name DOCUMENT ME! * @param key DOCUMENT ME! */ private void createStyle(String name, String key) { HighlightModel model = new HighlightModel(key); Style style = addStyle(name, getStyle(DEFAULT_STYLE)); style.addAttribute(StyleConstants.Foreground, model.getColor()); style.addAttribute(StyleConstants.FontFamily, model.getFont()); } //~ Inner Classes ****************************************************************************** /** * DOCUMENT ME! * * @author $Author: amunoz $ * @version $Revision: 1.3 $ */ public class HighlightView extends PlainView { /** DOCUMENT ME! */ private Element element = null; /** * Creates a new HighlightView object. * * @param element DOCUMENT ME! */ public HighlightView(Element element) { super(element); this.element = element; } /** * DOCUMENT ME! * * @param lineIndex DOCUMENT ME! * @param g DOCUMENT ME! * @param x DOCUMENT ME! * @param y DOCUMENT ME! */ protected void drawLine(int lineIndex, Graphics g, int x, int y) { Element line = element.getElement(lineIndex); try { if (line.isLeaf()) { drawElement(lineIndex, line, g, x, y); } else { for (int i = 0; i < line.getElementCount(); i++) { Element elem = line.getElement(i); x = drawElement(lineIndex, elem, g, x, y); } } } catch (BadLocationException e) { log.error(e.getMessage(), e); } } /** * DOCUMENT ME! * * @param line DOCUMENT ME! * @param previous DOCUMENT ME! * @param g DOCUMENT ME! * @param x DOCUMENT ME! * @param y DOCUMENT ME! * @param p0 DOCUMENT ME! * @param p1 DOCUMENT ME! * * @return DOCUMENT ME! * * @throws BadLocationException DOCUMENT ME! */ protected int drawUnselectedText(HighlightPlainDocument.LineElement line, HighlightPlainDocument.LineElement previous, Graphics g, int x, int y, int p0, int p1) throws BadLocationException { Document doc = getDocument(); String text = doc.getText(p0, p1 - p0); if (previous == null) { tokenizer.reinit(text); } else { tokenizer.reinit(text, previous.getLastState()); } Tokenizer.Token token = null; int lastPosition = 0; Tokenizer.RuntimeState lastState = tokenizer.getCurrentState(); do { token = tokenizer.nextToken(lastPosition); if (token != null) { if (lastPosition < token.getPosition()) { int type = lastState.getDefaultToken(); x = draw(type, x, y, g, p0 + lastPosition, p0 + token.getPosition()); lastPosition += (token.getPosition() - lastPosition); } int type = token.getType(); if (type == Syntax.END) { type = lastState.getDefaultToken(); } x = draw(type, x, y, g, p0 + token.getPosition(), p0 + token.getPosition() + token.getLength()); lastPosition += token.getLength(); lastState = tokenizer.getCurrentState(); } } while (token != null); if ((p0 + lastPosition) < p1) { int type = lastState.getDefaultToken(); x = draw(type, x, y, g, p0 + lastPosition, p1); } return x; } /** * DOCUMENT ME! * * @param type DOCUMENT ME! * @param x DOCUMENT ME! * @param y DOCUMENT ME! * @param g DOCUMENT ME! * @param p0 DOCUMENT ME! * @param p1 DOCUMENT ME! * * @return DOCUMENT ME! * * @throws BadLocationException DOCUMENT ME! */ private int draw(int type, int x, int y, Graphics g, int p0, int p1) throws BadLocationException { Style style = getTokenStyle(type); if (style != null) { Color color = (Color) style.getAttribute(StyleConstants.Foreground); Font font = (Font) style.getAttribute(StyleConstants.FontFamily); g.setColor(color); g.setFont(font); } Document doc = getDocument(); Segment segment = getLineBuffer(); doc.getText(p0, p1 - p0, segment); return Utilities.drawTabbedText(segment, x, y, g, this, p0); } /** * DOCUMENT ME! * * @param lineIndex DOCUMENT ME! * @param line DOCUMENT ME! * @param g DOCUMENT ME! * @param x DOCUMENT ME! * @param y DOCUMENT ME! * * @return DOCUMENT ME! * * @throws BadLocationException DOCUMENT ME! */ private int drawElement(int lineIndex, Element line, Graphics g, int x, int y) throws BadLocationException { Element previous = null; if (lineIndex > 0) { previous = element.getElement(lineIndex - 1); } int p0 = line.getStartOffset(); int p1 = line.getEndOffset(); p1 = Math.min(getDocument().getLength(), p1); if (lineIndex == 0) { x += 0; } return drawUnselectedText((HighlightPlainDocument.LineElement) line, (HighlightPlainDocument.LineElement) previous, g, x, y, p0, p1); } } }