| // Copyright (C) 2011 Chan Wai Shing |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| package prettify; |
| |
| import java.awt.Color; |
| import java.awt.Font; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.swing.text.SimpleAttributeSet; |
| import javax.swing.text.StyleConstants; |
| |
| /** |
| * Theme for the Java Prettify. |
| * <p>To make a new theme, either extending this class of initiate this class and set the parameter by the setter. |
| * For the default value, please refer to the constructor.</p> |
| * @author Chan Wai Shing <cws1989@gmail.com> |
| */ |
| public class Theme { |
| |
| /** |
| * Indicate whether it is in debug mode or not. |
| */ |
| protected final static boolean debug; |
| |
| static { |
| String debugMode = System.getProperty("PrettifyDebugMode"); |
| debug = debugMode == null || !debugMode.equals("true") ? false : true; |
| } |
| /** |
| * The font of the script text. |
| */ |
| protected Font font; |
| /** |
| * The background color of the script text area. |
| */ |
| protected Color background; |
| /** |
| * The background color of the highlighted line of script text. |
| */ |
| protected Color highlightedBackground; |
| /** |
| * Gutter (line number column on the left) |
| */ |
| /** |
| * The color of the gutter text. |
| */ |
| protected Color gutterText; |
| /** |
| * The color of the border that joint the gutter and the script text panel. |
| */ |
| protected Color gutterBorderColor; |
| /** |
| * The width of the border that joint the gutter and the script text panel. |
| */ |
| protected int gutterBorderWidth; |
| /** |
| * The font of the gutter text. |
| */ |
| protected Font gutterTextFont; |
| /** |
| * The minimum padding from 'the leftmost of the line number text' to 'the left margin'. |
| */ |
| protected int gutterTextPaddingLeft; |
| /** |
| * The minimum padding from 'the rightmost of the line number text' to 'the right margin' (not to the gutter border). |
| */ |
| protected int gutterTextPaddingRight; |
| protected Style string; |
| protected Style keyword; |
| protected Style comment; |
| protected Style type; |
| protected Style literal; |
| protected Style punctuation; |
| protected Style plain; |
| protected Style tag; |
| protected Style declaration; |
| protected Style source; |
| protected Style attributeName; |
| protected Style attributeValue; |
| protected Style noCode; |
| protected Style openBracket; |
| protected Style closeBracket; |
| protected Style variable; |
| protected Style function; |
| |
| /** |
| * Constructor.<br /> |
| * <p> |
| * <b>Default value:</b><br /> |
| * <ul> |
| * <li>font: Consolas 12pt</li> |
| * <li>background: white</li> |
| * <li>gutter text: black</li> |
| * <li>gutter border: R: 184, G: 184, B: 184</li> |
| * <li>gutter border width: 3px</li> |
| * <li>gutter text font: Consolas 12pt</li> |
| * <li>gutter text padding-left: 7px</li> |
| * <li>gutter text padding-right: 7px</li> |
| * <li>plain, comments, string, keyword, preprocessor, variable, value, functions, constants, script, scriptBackground, color1, color2, color3: no style set</li> |
| * </ul> |
| * </p> |
| */ |
| public Theme() { |
| font = new Font("Consolas", Font.PLAIN, 12); |
| background = Color.white; |
| |
| highlightedBackground = Color.gray; |
| |
| gutterText = Color.black; |
| gutterBorderColor = new Color(184, 184, 184); |
| gutterBorderWidth = 3; |
| gutterTextFont = new Font("Consolas", Font.PLAIN, 12); |
| gutterTextPaddingLeft = 7; |
| gutterTextPaddingRight = 7; |
| |
| string = new Style(); |
| keyword = new Style(); |
| comment = new Style(); |
| type = new Style(); |
| literal = new Style(); |
| punctuation = new Style(); |
| plain = new Style(); |
| tag = new Style(); |
| declaration = new Style(); |
| source = new Style(); |
| attributeName = new Style(); |
| attributeValue = new Style(); |
| noCode = new Style(); |
| openBracket = new Style(); |
| closeBracket = new Style(); |
| variable = new Style(); |
| function = new Style(); |
| } |
| |
| /** |
| * Apply the theme to the row header panel. |
| * @param rowHeader the row header to apply theme on |
| */ |
| public void setTheme(JTextComponentRowHeader rowHeader) { |
| rowHeader.setBackground(background); |
| rowHeader.setHighlightedColor(background); |
| |
| rowHeader.setForeground(gutterText); |
| rowHeader.setBorderColor(gutterBorderColor); |
| rowHeader.setBorderWidth(gutterBorderWidth); |
| rowHeader.setFont(gutterTextFont); |
| rowHeader.setPaddingLeft(gutterTextPaddingLeft); |
| rowHeader.setPaddingRight(gutterTextPaddingRight); |
| } |
| |
| /** |
| * Get the {@link prettify.Theme.Style} by keyword. |
| * @param key the keyword, possible values: plain, comments, string, keyword, preprocessor, variable, value, functions, constants, script, scriptBackground, color1, color2 or color3 |
| * @return the {@link prettify.Theme.Style} related to the {@code key}; if the style related to the <code>key</code> not exist, the style of 'plain' will return. |
| */ |
| public Style getStyle(String key) { |
| if (key.equals("str")) { |
| return string; |
| } else if (key.equals("kwd")) { |
| return keyword; |
| } else if (key.equals("com")) { |
| return comment; |
| } else if (key.equals("typ")) { |
| return type; |
| } else if (key.equals("lit")) { |
| return literal; |
| } else if (key.equals("pun")) { |
| return punctuation; |
| } else if (key.equals("pln")) { |
| return plain; |
| } else if (key.equals("tag")) { |
| return tag; |
| } else if (key.equals("dec")) { |
| return declaration; |
| } else if (key.equals("src")) { |
| return source; |
| } else if (key.equals("atn")) { |
| return attributeName; |
| } else if (key.equals("atv")) { |
| return attributeValue; |
| } else if (key.equals("nocode")) { |
| return noCode; |
| } else if (key.equals("opn")) { |
| return openBracket; |
| } else if (key.equals("clo")) { |
| return closeBracket; |
| } else if (key.equals("var")) { |
| return variable; |
| } else if (key.equals("fun")) { |
| return function; |
| } else { |
| // key not exist |
| return plain; |
| } |
| } |
| |
| /** |
| * The font of the script text. |
| */ |
| public Font getFont() { |
| return font; |
| } |
| |
| /** |
| * The font of the script text. |
| */ |
| public void setFont(Font font) { |
| if (font == null) { |
| throw new NullPointerException("argument 'font' cannot be null"); |
| } |
| this.font = font; |
| } |
| |
| /** |
| * The background color of the script text area. |
| */ |
| public Color getBackground() { |
| return background; |
| } |
| |
| /** |
| * The background color of the script text area. |
| */ |
| public void setBackground(Color background) { |
| if (background == null) { |
| throw new NullPointerException("argument 'background' cannot be null"); |
| } |
| this.background = background; |
| } |
| |
| /** |
| * The background color of the highlighted line of script text. |
| */ |
| public Color getHighlightedBackground() { |
| return highlightedBackground; |
| } |
| |
| /** |
| * The background color of the highlighted line of script text. |
| */ |
| public void setHighlightedBackground(Color highlightedBackground) { |
| if (highlightedBackground == null) { |
| throw new NullPointerException("argument 'highlightedBackground' cannot be null"); |
| } |
| this.highlightedBackground = highlightedBackground; |
| } |
| |
| /** |
| * The color of the gutter text. |
| */ |
| public Color getGutterText() { |
| return gutterText; |
| } |
| |
| /** |
| * The color of the gutter text. |
| */ |
| public void setGutterText(Color gutterText) { |
| if (gutterText == null) { |
| throw new NullPointerException("argument 'gutterText' cannot be null"); |
| } |
| this.gutterText = gutterText; |
| } |
| |
| /** |
| * The color of the border that joint the gutter and the script text panel. |
| */ |
| public Color getGutterBorderColor() { |
| return gutterBorderColor; |
| } |
| |
| /** |
| * The color of the border that joint the gutter and the script text panel. |
| */ |
| public void setGutterBorderColor(Color gutterBorderColor) { |
| if (gutterBorderColor == null) { |
| throw new NullPointerException("argument 'gutterBorderColor' cannot be null"); |
| } |
| this.gutterBorderColor = gutterBorderColor; |
| } |
| |
| /** |
| * The width of the border that joint the gutter and the script text panel. |
| */ |
| public int getGutterBorderWidth() { |
| return gutterBorderWidth; |
| } |
| |
| /** |
| * The width of the border that joint the gutter and the script text panel. |
| */ |
| public void setGutterBorderWidth(int gutterBorderWidth) { |
| this.gutterBorderWidth = gutterBorderWidth; |
| } |
| |
| /** |
| * The font of the gutter text. |
| */ |
| public Font getGutterTextFont() { |
| return gutterTextFont; |
| } |
| |
| /** |
| * The font of the gutter text. |
| */ |
| public void setGutterTextFont(Font gutterTextFont) { |
| if (gutterTextFont == null) { |
| throw new NullPointerException("argument 'gutterTextFont' cannot be null"); |
| } |
| this.gutterTextFont = gutterTextFont; |
| } |
| |
| /** |
| * The minimum padding from 'the leftmost of the line number text' to 'the left margin'. |
| */ |
| public int getGutterTextPaddingLeft() { |
| return gutterTextPaddingLeft; |
| } |
| |
| /** |
| * The minimum padding from 'the leftmost of the line number text' to 'the left margin'. |
| */ |
| public void setGutterTextPaddingLeft(int gutterTextPaddingLeft) { |
| this.gutterTextPaddingLeft = gutterTextPaddingLeft; |
| } |
| |
| /** |
| * The minimum padding from 'the rightmost of the line number text' to 'the right margin' (not to the gutter border). |
| */ |
| public int getGutterTextPaddingRight() { |
| return gutterTextPaddingRight; |
| } |
| |
| /** |
| * The minimum padding from 'the rightmost of the line number text' to 'the right margin' (not to the gutter border). |
| */ |
| public void setGutterTextPaddingRight(int gutterTextPaddingRight) { |
| this.gutterTextPaddingRight = gutterTextPaddingRight; |
| } |
| |
| public Style getString() { |
| return string; |
| } |
| |
| public void setString(Style string) { |
| this.string = string; |
| } |
| |
| public Style getKeyword() { |
| return keyword; |
| } |
| |
| public void setKeyword(Style keyword) { |
| this.keyword = keyword; |
| } |
| |
| public Style getComment() { |
| return comment; |
| } |
| |
| public void setComment(Style comment) { |
| this.comment = comment; |
| } |
| |
| public Style getType() { |
| return type; |
| } |
| |
| public void setType(Style type) { |
| this.type = type; |
| } |
| |
| public Style getLiteral() { |
| return literal; |
| } |
| |
| public void setLiteral(Style literal) { |
| this.literal = literal; |
| } |
| |
| public Style getPunctuation() { |
| return punctuation; |
| } |
| |
| public void setPunctuation(Style punctuation) { |
| this.punctuation = punctuation; |
| } |
| |
| public Style getPlain() { |
| return plain; |
| } |
| |
| public void setPlain(Style plain) { |
| this.plain = plain; |
| } |
| |
| public Style getTag() { |
| return tag; |
| } |
| |
| public void setTag(Style tag) { |
| this.tag = tag; |
| } |
| |
| public Style getDeclaration() { |
| return declaration; |
| } |
| |
| public void setDeclaration(Style declaration) { |
| this.declaration = declaration; |
| } |
| |
| public Style getSource() { |
| return source; |
| } |
| |
| public void setSource(Style source) { |
| this.source = source; |
| } |
| |
| public Style getAttributeName() { |
| return attributeName; |
| } |
| |
| public void setAttributeName(Style attributeName) { |
| this.attributeName = attributeName; |
| } |
| |
| public Style getAttributeValue() { |
| return attributeValue; |
| } |
| |
| public void setAttributeValue(Style attributeValue) { |
| this.attributeValue = attributeValue; |
| } |
| |
| public Style getNoCode() { |
| return noCode; |
| } |
| |
| public void setNoCode(Style noCode) { |
| this.noCode = noCode; |
| } |
| |
| public Style getOpenBracket() { |
| return openBracket; |
| } |
| |
| public void setOpenBracket(Style openBracket) { |
| this.openBracket = openBracket; |
| } |
| |
| public Style getCloseBracket() { |
| return closeBracket; |
| } |
| |
| public void setCloseBracket(Style closeBracket) { |
| this.closeBracket = closeBracket; |
| } |
| |
| public Style getVariable() { |
| return variable; |
| } |
| |
| public void setVariable(Style variable) { |
| this.variable = variable; |
| } |
| |
| public Style getFunction() { |
| return function; |
| } |
| |
| public void setFunction(Style function) { |
| this.function = function; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public Theme clone() { |
| Theme object = null; |
| try { |
| object = (Theme) super.clone(); |
| object.font = font; |
| object.background = background; |
| object.highlightedBackground = highlightedBackground; |
| object.gutterText = gutterText; |
| object.gutterBorderColor = gutterBorderColor; |
| object.gutterBorderWidth = gutterBorderWidth; |
| object.gutterTextFont = gutterTextFont; |
| object.gutterTextPaddingLeft = gutterTextPaddingLeft; |
| object.gutterTextPaddingRight = gutterTextPaddingRight; |
| object.string = string.clone(); |
| object.keyword = keyword.clone(); |
| object.comment = comment.clone(); |
| object.type = type.clone(); |
| object.literal = literal.clone(); |
| object.punctuation = punctuation.clone(); |
| object.plain = plain.clone(); |
| object.tag = tag.clone(); |
| object.declaration = declaration.clone(); |
| object.source = source.clone(); |
| object.attributeName = attributeName.clone(); |
| object.attributeValue = attributeValue.clone(); |
| object.noCode = noCode.clone(); |
| object.openBracket = openBracket.clone(); |
| object.closeBracket = closeBracket.clone(); |
| object.variable = variable.clone(); |
| object.function = function.clone(); |
| } catch (CloneNotSupportedException ex) { |
| if (debug) { |
| Logger.getLogger(Theme.class.getName()).log(Level.WARNING, null, ex); |
| } |
| } |
| return object; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| |
| sb.append(getClass().getName()); |
| sb.append(": "); |
| sb.append("font: ").append(getFont()); |
| sb.append(", "); |
| sb.append("background: ").append(getBackground()); |
| sb.append(", "); |
| sb.append("highlightedBackground: ").append(getHighlightedBackground()); |
| sb.append(", "); |
| sb.append("gutterText: ").append(getGutterText()); |
| sb.append(", "); |
| sb.append("gutterBorderColor: ").append(getGutterBorderColor()); |
| sb.append(", "); |
| sb.append("gutterBorderWidth: ").append(getGutterBorderWidth()); |
| sb.append(", "); |
| sb.append("gutterTextFont: ").append(getGutterTextFont()); |
| sb.append(", "); |
| sb.append("gutterTextPaddingLeft: ").append(getGutterTextPaddingLeft()); |
| sb.append(", "); |
| sb.append("gutterTextPaddingRight: ").append(getGutterTextPaddingRight()); |
| sb.append(", "); |
| sb.append("string: ").append(getString()); |
| sb.append(", "); |
| sb.append("keyword: ").append(getKeyword()); |
| sb.append(", "); |
| sb.append("comment: ").append(getComment()); |
| sb.append(", "); |
| sb.append("type: ").append(getType()); |
| sb.append(", "); |
| sb.append("literal: ").append(getLiteral()); |
| sb.append(", "); |
| sb.append("punctuation: ").append(getPunctuation()); |
| sb.append(", "); |
| sb.append("plain: ").append(getPlain()); |
| sb.append(", "); |
| sb.append("tag: ").append(getTag()); |
| sb.append(", "); |
| sb.append("declaration: ").append(getDeclaration()); |
| sb.append(", "); |
| sb.append("source: ").append(getSource()); |
| sb.append(", "); |
| sb.append("attributeName: ").append(getAttributeName()); |
| sb.append(", "); |
| sb.append("attributeValue: ").append(getAttributeValue()); |
| sb.append(", "); |
| sb.append("noCode: ").append(getNoCode()); |
| sb.append(", "); |
| sb.append("openBracket: ").append(getOpenBracket()); |
| sb.append(", "); |
| sb.append("closeBracket: ").append(getCloseBracket()); |
| sb.append(", "); |
| sb.append("variable: ").append(getVariable()); |
| sb.append(", "); |
| sb.append("function: ").append(getFunction()); |
| |
| return sb.toString(); |
| } |
| |
| /** |
| * The style used by {@link prettify.theme} as those of CSS styles. |
| */ |
| public static class Style { |
| |
| protected boolean bold; |
| protected Color color; |
| /** |
| * The background color, null means no background color is set. |
| */ |
| protected Color background; |
| protected boolean underline; |
| protected boolean italic; |
| |
| /** |
| * Constructor. |
| * <p> |
| * <b>Default values:</b><br /> |
| * <ul> |
| * <li>bold: false;</li> |
| * <li>color: black;</li> |
| * <li>background: null;</li> |
| * <li>underline: false;</li> |
| * <li>italic: false;</li> |
| * </ul> |
| * </p> |
| */ |
| public Style() { |
| bold = false; |
| color = Color.black; |
| background = null; |
| underline = false; |
| italic = false; |
| } |
| |
| /** |
| * Apply the style to the AttributeSet. |
| * Note that the AttributeSet should only be set by this function once or some unexpected style may appear. |
| * @param attributeSet the AttributeSet to set the style on |
| */ |
| public void setAttributeSet(SimpleAttributeSet attributeSet) { |
| if (attributeSet == null) { |
| return; |
| } |
| StyleConstants.setBold(attributeSet, bold); |
| StyleConstants.setForeground(attributeSet, color); |
| if (background != null) { |
| StyleConstants.setBackground(attributeSet, background); |
| } else { |
| attributeSet.removeAttribute(StyleConstants.Background); |
| } |
| StyleConstants.setUnderline(attributeSet, underline); |
| StyleConstants.setItalic(attributeSet, italic); |
| } |
| |
| /** |
| * Get the AttributeSet from this style. |
| * @return the AttributeSet |
| */ |
| public SimpleAttributeSet getAttributeSet() { |
| SimpleAttributeSet attributeSet = new SimpleAttributeSet(); |
| StyleConstants.setBold(attributeSet, bold); |
| StyleConstants.setForeground(attributeSet, color); |
| if (background != null) { |
| StyleConstants.setBackground(attributeSet, background); |
| } |
| StyleConstants.setUnderline(attributeSet, underline); |
| StyleConstants.setItalic(attributeSet, italic); |
| return attributeSet; |
| } |
| |
| /** |
| * Get the background color. |
| * @return the background color or null if no color is set |
| */ |
| public Color getBackground() { |
| return background; |
| } |
| |
| /** |
| * Set the background color. |
| * @param background input null means do not set the background |
| */ |
| public void setBackground(Color background) { |
| if (background == null) { |
| throw new NullPointerException("argument 'background' cannot be null"); |
| } |
| this.background = background; |
| } |
| |
| public boolean isBold() { |
| return bold; |
| } |
| |
| public void setBold(boolean bold) { |
| this.bold = bold; |
| } |
| |
| public Color getColor() { |
| return color; |
| } |
| |
| public void setColor(Color color) { |
| if (color == null) { |
| throw new NullPointerException("argument 'color' cannot be null"); |
| } |
| this.color = color; |
| } |
| |
| public boolean isItalic() { |
| return italic; |
| } |
| |
| public void setItalic(boolean italic) { |
| this.italic = italic; |
| } |
| |
| public boolean isUnderline() { |
| return underline; |
| } |
| |
| public void setUnderline(boolean underline) { |
| this.underline = underline; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (obj == null || !(obj instanceof Style)) { |
| return false; |
| } |
| if (obj == this) { |
| return true; |
| } |
| Style _object = (Style) obj; |
| return _object.bold == bold && _object.color.equals(color) && _object.background.equals(background) |
| && _object.underline == underline && _object.italic == italic; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public Style clone() { |
| Style object = null; |
| try { |
| object = (Style) super.clone(); |
| object.bold = bold; |
| object.color = color; |
| object.background = background; |
| object.underline = underline; |
| object.italic = italic; |
| } catch (CloneNotSupportedException ex) { |
| } |
| return object; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| |
| sb.append(getClass().getName()); |
| sb.append(": "); |
| sb.append("bold: ").append(bold); |
| sb.append(", "); |
| sb.append("color: ").append(color); |
| sb.append(", "); |
| sb.append("bg: ").append(background); |
| sb.append(", "); |
| sb.append("underline: ").append(underline); |
| sb.append(", "); |
| sb.append("italic: ").append(italic); |
| |
| return sb.toString(); |
| } |
| } |
| } |