/* * Created on Nov 3, 2007 */ package net.atlanticbb.tantlinger.ui.text; import java.awt.Color; import java.awt.Font; import java.io.InputStream; import java.util.Properties; import java.util.StringTokenizer; import novaworx.syntax.SyntaxFactory; import novaworx.syntax.Token; import novaworx.textpane.SyntaxDocument; import novaworx.textpane.SyntaxStyle; import novaworx.textpane.SyntaxTextPane; /** * @author Bob Tantlinger * */ public class SourceCodeEditor extends SyntaxTextPane { /** * */ private static final long serialVersionUID = 1L; /** * */ public SourceCodeEditor() { super(); SyntaxFactory.setSyntaxCatalog(getClass().getResource("/resources/syntax.catalog.xml")); SyntaxFactory.loadSyntaxes(); setLineHighlight(true); setBracketHighlight(true); setAntiAlias(true); setOpaque(true); setCaretOnDelay(500); setCaretOffDelay(500); setFont(new Font("Default", Font.PLAIN, 12)); /* Load default theme */ Properties themes = new Properties(); InputStream in = null; try { in = getClass().getResource("/net/atlanticbb/tantlinger/ui/text/syntax.properties").openStream(); themes.load(in); setTheme(themes, "default"); } catch(Exception e) { e.printStackTrace(); } finally { try { in.close(); } catch(Exception ex) { } } } public void setTheme(Properties props) { String prefix = "default"; try { SyntaxDocument d = (SyntaxDocument)getDocument(); prefix = d.getSyntax().getName(); } catch(ClassCastException ex) { } setTheme(props, prefix); } /** * Set a color theme from a properties file * @param props The Properties object * @param prefix The prefix to use when getting the keys */ public void setTheme(Properties props, String prefix) //throws Exception { SyntaxStyle[] aStyles = getSyntaxStyles(); aStyles[Token.COMMENT1].setForeground(parseColor(props.getProperty(prefix + ".comment1.fg"))); aStyles[Token.COMMENT1].setBackground(parseColor(props.getProperty(prefix + ".comment1.bg"))); aStyles[Token.COMMENT1].setFontStyle(parseFont(props.getProperty(prefix + ".comment1.font"))); aStyles[Token.COMMENT2].setForeground(parseColor(props.getProperty(prefix + ".comment2.fg"))); aStyles[Token.COMMENT2].setBackground(parseColor(props.getProperty(prefix + ".comment2.bg"))); aStyles[Token.COMMENT2].setFontStyle(parseFont(props.getProperty(prefix + ".comment2.font"))); aStyles[Token.COMMENT3].setForeground(parseColor(props.getProperty(prefix + ".comment3.fg"))); aStyles[Token.COMMENT3].setBackground(parseColor(props.getProperty(prefix + ".comment3.bg"))); aStyles[Token.COMMENT3].setFontStyle(parseFont(props.getProperty(prefix + ".comment3.font"))); aStyles[Token.DIGIT].setForeground(parseColor(props.getProperty(prefix + ".digit.fg"))); aStyles[Token.DIGIT].setBackground(parseColor(props.getProperty(prefix + ".digit.bg"))); aStyles[Token.DIGIT].setFontStyle(parseFont(props.getProperty(prefix + ".digit.font"))); aStyles[Token.LITERAL1].setForeground(parseColor(props.getProperty(prefix + ".literal1.fg"))); aStyles[Token.LITERAL1].setBackground(parseColor(props.getProperty(prefix + ".literal1.bg"))); aStyles[Token.LITERAL1].setFontStyle(parseFont(props.getProperty(prefix + ".literal1.font"))); aStyles[Token.LITERAL2].setForeground(parseColor(props.getProperty(prefix + ".literal2.fg"))); aStyles[Token.LITERAL2].setBackground(parseColor(props.getProperty(prefix + ".literal2.bg"))); aStyles[Token.LITERAL2].setFontStyle(parseFont(props.getProperty(prefix + ".literal2.font"))); aStyles[Token.KEYWORD1].setForeground(parseColor(props.getProperty(prefix + ".keyword1.fg"))); aStyles[Token.KEYWORD1].setBackground(parseColor(props.getProperty(prefix + ".keyword1.bg"))); aStyles[Token.KEYWORD1].setFontStyle(parseFont(props.getProperty(prefix + ".keyword1.font"))); aStyles[Token.KEYWORD2].setForeground(parseColor(props.getProperty(prefix + ".keyword2.fg"))); aStyles[Token.KEYWORD2].setBackground(parseColor(props.getProperty(prefix + ".keyword2.bg"))); aStyles[Token.KEYWORD2].setFontStyle(parseFont(props.getProperty(prefix + ".keyword2.font"))); aStyles[Token.KEYWORD3].setForeground(parseColor(props.getProperty(prefix + ".keyword3.fg"))); aStyles[Token.KEYWORD3].setBackground(parseColor(props.getProperty(prefix + ".keyword3.bg"))); aStyles[Token.KEYWORD3].setFontStyle(parseFont(props.getProperty(prefix + ".keyword3.font"))); aStyles[Token.KEYWORD4].setForeground(parseColor(props.getProperty(prefix + ".keyword4.fg"))); aStyles[Token.KEYWORD4].setBackground(parseColor(props.getProperty(prefix + ".keyword4.bg"))); aStyles[Token.KEYWORD4].setFontStyle(parseFont(props.getProperty(prefix + ".keyword4.font"))); aStyles[Token.KEYWORD5].setForeground(parseColor(props.getProperty(prefix + ".keyword5.fg"))); aStyles[Token.KEYWORD5].setBackground(parseColor(props.getProperty(prefix + ".keyword5.bg"))); aStyles[Token.KEYWORD5].setFontStyle(parseFont(props.getProperty(prefix + ".keyword5.font"))); aStyles[Token.FUNCTION].setForeground(parseColor(props.getProperty(prefix + ".function.fg"))); aStyles[Token.FUNCTION].setBackground(parseColor(props.getProperty(prefix + ".function.bg"))); aStyles[Token.FUNCTION].setFontStyle(parseFont(props.getProperty(prefix + ".function.font"))); aStyles[Token.OPERATOR].setForeground(parseColor(props.getProperty(prefix + ".operator.fg"))); aStyles[Token.OPERATOR].setBackground(parseColor(props.getProperty(prefix + ".operator.bg"))); aStyles[Token.OPERATOR].setFontStyle(parseFont(props.getProperty(prefix + ".operator.font"))); aStyles[Token.MARKUP].setForeground(parseColor(props.getProperty(prefix + ".markup.fg"))); aStyles[Token.MARKUP].setBackground(parseColor(props.getProperty(prefix + ".markup.bg"))); aStyles[Token.MARKUP].setFontStyle(parseFont(props.getProperty(prefix + ".markup.font"))); aStyles[Token.LABEL].setForeground(parseColor(props.getProperty(prefix + ".label.fg"))); aStyles[Token.LABEL].setBackground(parseColor(props.getProperty(prefix + ".label.bg"))); aStyles[Token.LABEL].setFontStyle(parseFont(props.getProperty(prefix + ".label.font"))); aStyles[Token.INVALID].setForeground(parseColor(props.getProperty(prefix + ".invalid.fg"))); aStyles[Token.INVALID].setBackground(parseColor(props.getProperty(prefix + ".invalid.bg"))); aStyles[Token.INVALID].setFontStyle(parseFont(props.getProperty(prefix + ".invalid.font"))); aStyles[Token.NULL].setFontStyle(parseFont(props.getProperty(prefix + ".null.font"))); setForeground(parseColor(props.getProperty(prefix + ".text.fg"))); setBackground(parseColor(props.getProperty(prefix + ".text.bg"))); setCaretColor(parseColor(props.getProperty(prefix + ".caret.fg"))); setBracketHighlightColor(parseColor(props.getProperty(prefix + ".brackethighlight.fg"))); //setSelectionColor(parseColor(props.getProperty(prefix + ".selectioncolor.bg"))); setLineHighlightColor(parseColor(props.getProperty(prefix + ".linehighlight.fg"))); /*gutter.setForeground(parseColor(props.getProperty(prefix + ".gutter.fg"))); gutter.setBackground(parseColor(props.getProperty(prefix + ".gutter.bg"))); gutter.setDividerForeground(parseColor(props.getProperty(prefix + ".divider.fg"))); gutter.setDividerBackground(parseColor(props.getProperty(prefix + ".divider.bg"))); gutter.setCurrentLineForeground(parseColor(props.getProperty(prefix + ".currentline.fg"))); gutter.setCurrentLineBackground(parseColor(props.getProperty(prefix + ".currentline.bg"))); gutter.setLineIntervalForeground(parseColor(props.getProperty(prefix + ".lineinterval.fg"))); gutter.setLineIntervalBackground(parseColor(props.getProperty(prefix + ".lineinterval.bg"))); gutter.setSelectionForeground(parseColor(props.getProperty(prefix + ".gutterselection.fg"))); gutter.setSelectionBackground(parseColor(props.getProperty(prefix + ".gutterselection.bg"))); gutter.setBracketScopeForeground(parseColor(props.getProperty(prefix + ".bracketscope.fg"))); gutter.setBracketScopeBackground(parseColor(props.getProperty(prefix + ".bracketscope.bg")));*/ } /** * Parse a color from the syntax.properties file. It can have the format * RRGGBB in hex or AARRGGBB (with alpha blending) * * @param color The color string * @return A color object */ private Color parseColor(String color) //throws Exception { if(color == null) return new Color(0, 0, 0, 0); try { if(color.length() == 6) { int r = Integer.parseInt(color.substring(0, 2), 16); int g = Integer.parseInt(color.substring(2, 4), 16); int b = Integer.parseInt(color.substring(4, 6), 16); return new Color(r, g, b); } else if(color.length() == 8) { int a = Integer.parseInt(color.substring(0, 2), 16); int r = Integer.parseInt(color.substring(2, 4), 16); int g = Integer.parseInt(color.substring(4, 6), 16); int b = Integer.parseInt(color.substring(6, 8), 16); return new Color(r, g, b, a); } else { //throw new Exception("Invalid color syntax"); } } catch(NumberFormatException e) { //throw new Exception("Invalid color data", e); } return Color.black; } /** * Parse a font from the syntax.properties file. Takes a comma-separated * list of the plain,bold and italic parameters * * @param font The font string * @return A font style constant */ private int parseFont(String font) //throws Exception { int flags = Font.PLAIN; if(font != null) { StringTokenizer tokenizer = new StringTokenizer(font, ","); while(tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken().toLowerCase(); if(token.equals("bold")) { flags |= Font.BOLD; } else if(token.equals("italic")) { flags |= Font.ITALIC; } else if(token.equals("plain")) { /* Ignore */ } /*else { throw new Exception("Unknown font attribute"); }*/ } } return flags; } }