package edu.princeton.swing.text; import java.awt.*; /** * HighlightStyle encapsulates the stylistic variations which different highlights in a * THighlightedTextArea may take. This class is immutable. * * @author btsang * @version 7.1 */ public class HighlightStyle { /** * An array to convert an integer between 0 and 16 to a hexidecimal digit. */ public static final char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** * The plain black style. */ public static final HighlightStyle DEFAULT_STYLE = new HighlightStyle(Color.black, false, false); private Color color; private boolean bold; private boolean italic; /** * Instantiates a new HighlightStyle. */ public HighlightStyle(Color color, boolean bold, boolean italic) { if (color == null) throw new NullPointerException(); this.color = color; this.bold = bold; this.italic = italic; } /** * Returns the color which the highlighted text should take. * * @return The color which the highlighted text should take. */ public Color getColor() { return color; } /** * Returns wheter or not the highlighted text should be bold. * * @return True iff the highlighted text should be bold. */ public boolean isBold() { return bold; } /** * Returns wheter or not the highlighted text should be italicized. * * @return True iff the highlighted text should be italicized. */ public boolean isItalic() { return italic; } /** * Returns the style mask which can be sent straight to the constructor of Font. * * @return The style mask which can be used in the constructor of Font. */ public int getStyleMask() { return (bold?Font.BOLD:0) | (italic?Font.ITALIC:0); } /** * Returns true if two HighlightStyles are identical. * * @param obj The object to compare this HighlightStyle with. * @return True iff obj is a HighlightStyle and if the fields are equal. */ public boolean equals(Object obj) { if (obj != null && obj instanceof HighlightStyle) { HighlightStyle style = (HighlightStyle)obj; return (bold == style.bold) && (italic == style.italic) && color.equals(style.color); } return false; } /** * Encodes the HighlightStyle in a format that can be read by parseStyle(). * * @return A string which can be read by parseStyle(). */ public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append('#'); int tempInt; tempInt = color.getRed(); buffer.append(HEX_DIGITS[(tempInt >> 4) & 0xF]); buffer.append(HEX_DIGITS[ tempInt & 0xF]); tempInt = color.getGreen(); buffer.append(HEX_DIGITS[(tempInt >> 4) & 0xF]); buffer.append(HEX_DIGITS[ tempInt & 0xF]); tempInt = color.getBlue(); buffer.append(HEX_DIGITS[(tempInt >> 4) & 0xF]); buffer.append(HEX_DIGITS[ tempInt & 0xF]); buffer.append('-'); if (bold) buffer.append("BOLD"); buffer.append('-'); if (italic) buffer.append("ITALIC"); return buffer.toString(); } /** * Decodes the string produced by toString() back into a HighlightStyle. If the string could * not be parsed, null is returned. * * @param string The string to parse. A null value will result in a NullPointerException. * @return The parsed HighlightStyle. Null is returned if the string was unparseable. */ public static HighlightStyle parseStyle(String string) { int length = string.length(); boolean bold, italic; if (length == 9) { if (string.endsWith("--")) { bold = false; italic = false; } else { return null; } } else if (length == 13) { if (string.endsWith("-BOLD-")) { bold = true; italic = false; } else { return null; } } else if (length == 15) { if (string.endsWith("--ITALIC")) { bold = false; italic = true; } else { return null; } } else if (length == 19) { if (string.endsWith("-BOLD-ITALIC")) { bold = true; italic = true; } else { return null; } } else { return null; } if (string.charAt(0) == '#' && isHexDigit(string.charAt(1)) && isHexDigit(string.charAt(2)) && isHexDigit(string.charAt(3)) && isHexDigit(string.charAt(4)) && isHexDigit(string.charAt(5)) && isHexDigit(string.charAt(6))) { return new HighlightStyle( new Color( 16 * hexDigitToInt(string.charAt(1)) + hexDigitToInt(string.charAt(2)), 16 * hexDigitToInt(string.charAt(3)) + hexDigitToInt(string.charAt(4)), 16 * hexDigitToInt(string.charAt(5)) + hexDigitToInt(string.charAt(6)) ), bold, italic ); } else { return null; } } /** * Returns whether or not a character is a hexidecimal digit. This test is case-insensitive. * * @param c The character to test. * @return True iff the c is a hexidecimal digit. */ public static boolean isHexDigit(char c) { return c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'; } /** * Returns the hexidecimal value of a character. This function is case-insensitive. * * @param c The character to convert. If this character is not a hex digit, an * IllegalArgumentException will be thrown. * @return The value c interpreted as a hexidecimal digit. */ public static int hexDigitToInt(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'A' && c <= 'F') return c - 'A' + 10; if (c >= 'a' && c <= 'f') return c - 'a' + 10; throw new IllegalArgumentException(); } }