| // Copyright (c) 2012 Chan Wai Shing | |
| // | |
| // Permission is hereby granted, free of charge, to any person obtaining | |
| // a copy of this software and associated documentation files (the | |
| // "Software"), to deal in the Software without restriction, including | |
| // without limitation the rights to use, copy, modify, merge, publish, | |
| // distribute, sublicense, and/or sell copies of the Software, and to | |
| // permit persons to whom the Software is furnished to do so, subject to | |
| // the following conditions: | |
| // | |
| // The above copyright notice and this permission notice shall be | |
| // included in all copies or substantial portions of the Software. | |
| // | |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
| // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
| // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
| // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| package syntaxhighlight; | |
| import java.awt.Color; | |
| import java.awt.Font; | |
| import java.util.HashMap; | |
| import java.util.Map; | |
| import java.util.logging.Logger; | |
| import javax.swing.text.SimpleAttributeSet; | |
| /** | |
| * Theme for the {@link SyntaxHighlighterPane} and | |
| * {@link JTextComponentRowHeader}. | |
| * | |
| * To make a new theme, either extending this class or initiate this class and | |
| * set parameters using setters. For the default value, find the comment of the | |
| * constructor. | |
| * | |
| * @author Chan Wai Shing <cws1989@gmail.com> | |
| */ | |
| public class Theme { | |
| private static final Logger LOG = Logger.getLogger(Theme.class.getName()); | |
| /** | |
| * 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 area. | |
| */ | |
| protected Color gutterBorderColor; | |
| /** | |
| * The width of the border that joint the gutter and the script text area. | |
| */ | |
| 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; | |
| /** | |
| * Text area. | |
| */ | |
| /** | |
| * The default style. When the style requested by {@link #getStyle(String)} | |
| * not exist, this will be returned. | |
| */ | |
| protected Style plain; | |
| /** | |
| * The styles of this theme. | |
| */ | |
| protected Map<String, Style> styles; | |
| /** | |
| * 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> | |
| * </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; | |
| plain = new Style(); | |
| styles = new HashMap<String, Style>(); | |
| } | |
| /** | |
| * Apply the theme to the row header panel. | |
| * @param rowHeader the row header to apply the 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); | |
| } | |
| /** | |
| * Set the default style. | |
| * @param plain the style | |
| */ | |
| public void setPlain(Style plain) { | |
| if (plain == null) { | |
| throw new NullPointerException("argument 'plain' cannot be null"); | |
| } | |
| this.plain = plain; | |
| } | |
| /** | |
| * Get the default style. | |
| * @return the style | |
| */ | |
| public Style getPlain() { | |
| return plain; | |
| } | |
| /** | |
| * Get the {@link AttributeSet} of {@code styleKeys}. For more than one | |
| * styles, separate the styles by space, e.g. 'plain comments'. | |
| * @param styleKeys the style keys with keys separated by space | |
| * @return the combined {@link AttributeSet} | |
| */ | |
| public SimpleAttributeSet getStylesAttributeSet(String styleKeys) { | |
| if (styleKeys.indexOf(' ') != -1) { | |
| SimpleAttributeSet returnAttributeSet = new SimpleAttributeSet(); | |
| String[] _keys = styleKeys.split(" "); | |
| for (String _key : _keys) { | |
| returnAttributeSet.addAttributes(getStyle(_key).getAttributeSet()); | |
| } | |
| return returnAttributeSet; | |
| } else { | |
| return getStyle(styleKeys).getAttributeSet(); | |
| } | |
| } | |
| /** | |
| * Add style. | |
| * @param styleKey the keyword of the style | |
| * @param style the style | |
| * @return see the return value of {@link Map#put(Object, Object)} | |
| */ | |
| public Style addStyle(String styleKey, Style style) { | |
| return styles.put(styleKey, style); | |
| } | |
| /** | |
| * Remove style by keyword. | |
| * @param styleKey the keyword of the style | |
| * @return see the return value of {@link Map#remove(Object)} | |
| */ | |
| public Style removeStyle(String styleKey) { | |
| return styles.remove(styleKey); | |
| } | |
| /** | |
| * Get the style by keyword. | |
| * @param key the keyword | |
| * @return the {@link syntaxhighlighter.theme.Style} related to the | |
| * {@code key}; if the style related to the {@code key} not exist, the | |
| * style of 'plain' will return. | |
| */ | |
| public Style getStyle(String key) { | |
| Style returnStyle = styles.get(key); | |
| return returnStyle != null ? returnStyle : plain; | |
| } | |
| /** | |
| * Get all styles. | |
| * @return the styles | |
| */ | |
| public Map<String, Style> getStyles() { | |
| return new HashMap<String, Style>(styles); | |
| } | |
| /** | |
| * Clear all styles. | |
| */ | |
| public void clearStyles() { | |
| styles.clear(); | |
| } | |
| /** | |
| * The font of the script text. | |
| * @return the font | |
| */ | |
| public Font getFont() { | |
| return font; | |
| } | |
| /** | |
| * The font of the script text. | |
| * @param font the font | |
| */ | |
| 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. | |
| * @return the color | |
| */ | |
| public Color getBackground() { | |
| return background; | |
| } | |
| /** | |
| * The background color of the script text area. | |
| * @param background the color | |
| */ | |
| 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. | |
| * @return the color | |
| */ | |
| public Color getHighlightedBackground() { | |
| return highlightedBackground; | |
| } | |
| /** | |
| * The background color of the highlighted line of script text. | |
| * @param highlightedBackground the color | |
| */ | |
| 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. | |
| * @return the color | |
| */ | |
| public Color getGutterText() { | |
| return gutterText; | |
| } | |
| /** | |
| * The color of the gutter text. | |
| * @param gutterText the color | |
| */ | |
| 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 area. | |
| * @return the color | |
| */ | |
| public Color getGutterBorderColor() { | |
| return gutterBorderColor; | |
| } | |
| /** | |
| * The color of the border that joint the gutter and the script text area. | |
| * @param gutterBorderColor the color | |
| */ | |
| 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 area. | |
| * @return the width in pixel | |
| */ | |
| public int getGutterBorderWidth() { | |
| return gutterBorderWidth; | |
| } | |
| /** | |
| * The width of the border that joint the gutter and the script text area. | |
| * @param gutterBorderWidth in pixel | |
| */ | |
| public void setGutterBorderWidth(int gutterBorderWidth) { | |
| this.gutterBorderWidth = gutterBorderWidth; | |
| } | |
| /** | |
| * The font of the gutter text. | |
| * @return the font | |
| */ | |
| public Font getGutterTextFont() { | |
| return gutterTextFont; | |
| } | |
| /** | |
| * The font of the gutter text. | |
| * @param gutterTextFont the font | |
| */ | |
| 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'. | |
| * @return the padding in pixel | |
| */ | |
| public int getGutterTextPaddingLeft() { | |
| return gutterTextPaddingLeft; | |
| } | |
| /** | |
| * The minimum padding from 'the leftmost of the line number text' to | |
| * 'the left margin'. | |
| * @param gutterTextPaddingLeft in pixel | |
| */ | |
| 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). | |
| * @return the padding in pixel | |
| */ | |
| 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). | |
| * @param gutterTextPaddingRight in pixel | |
| */ | |
| public void setGutterTextPaddingRight(int gutterTextPaddingRight) { | |
| this.gutterTextPaddingRight = gutterTextPaddingRight; | |
| } | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| @Override | |
| public Theme clone() { | |
| Theme object = null; | |
| try { | |
| object = (Theme) super.clone(); | |
| object.styles = new HashMap<String, Style>(); | |
| for (String key : styles.keySet()) { | |
| object.styles.put(key, styles.get(key).clone()); | |
| } | |
| } catch (CloneNotSupportedException ex) { | |
| } | |
| return object; | |
| } | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| @Override | |
| public String toString() { | |
| StringBuilder sb = new StringBuilder(); | |
| sb.append("["); | |
| 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("styles: "); | |
| for (String _key : styles.keySet()) { | |
| sb.append(_key).append(":").append(styles.get(_key)); | |
| } | |
| sb.append("]"); | |
| return sb.toString(); | |
| } | |
| } |