package com.onaro.util.jfc; import java.io.IOException; /** * This class assists in creating text for those Swing JComponents, * such as JLabel and JButton, that support certain HTML tags. It is * based on {@link StringBuilder}. *

* To use this class, create an instance of it and create a chain of method * calls. End the chain of calls with a call to the {@link #getText} method. * Use the provided static methods to format text before passing it to the * {@link #append (CharSequence)} method. *

* The builder's {@link #toString} method can be used to embed the output of * one builder in another builder. *

* Examples: *

 * JLabel label = new JLabel();
 * JComponentHtmlBuilder builder = new JComponentHtmlBuilder();
 * 
 * // Display two lines of plain text in the label.
 * label.setText (builder.append ("one", "two").getText());
 * 
 * // Add another line of text to the label, this time using a bold font.
 * label.setText (builder
 *               .appendBreak()
 *               .append (JComponentHtmlBuilder.bold ("three"))
 *               .getText());
 * 
 * // Display new text, using a red underscored font.
 * builder.clear();
 * label.setText (builder
 *               .append (JComponentHtmlBuilder.color (JComponentHtmlBuilder.Color.RED,
 *                        JComponentHtmlBuilder.underscore ("bad news")))
 *               .getText());
 * 
* @see How to Use HTML in Swing Components * for more information about using HTML in Swing components. */ public class JComponentHtmlBuilder implements CharSequence, Appendable { private final StringBuilder builder= new StringBuilder(); /** * HTML colors supported by {@link JComponentHtmlBuilder}. Only * the 16 basic VGA names are defined, though the current * version of HTML defines 130 more names. *

* The colors are: *

* @see HTML color names * for samples and more information about these colors. */ public enum Color { WHITE, SILVER, GRAY, BLACK, RED, MAROON, YELLOW, OLIVE, LIME, GREEN, AQUA, TEAL, BLUE, NAVY, FUCHSIA, PURPLE } @Override public int length() { return builder.length(); } @Override public char charAt (int index) { return builder.charAt (index); } @Override public CharSequence subSequence (int start, int end) { return builder.subSequence (start, end); } /** * @return HTML fragment without {@code } tag * @see java.lang.Object#toString() * @see #getText() */ @Override public String toString() { return builder.toString(); } /** * Appends a character. * @param character char value * @return this * @see StringBuilder#append (char) */ @Override public JComponentHtmlBuilder append (char character) throws IOException { builder.append (character); return this; } /** * Appends text with no additional formatting. * @param text * @return this * @see StringBuilder#append (CharSequence) */ @Override public JComponentHtmlBuilder append (CharSequence text) { builder.append (text); return this; } /** * Appends zero or more lines of text with breaks (newlines) * between each line. No other formatting is added to the text. * @param lines of text. If {@code null}, then {@code "null"} * (without the quotes) is appended. * @return this * @see #append (CharSequence) */ public JComponentHtmlBuilder append (CharSequence... lines) { if (lines == null) { builder.append ((String)null); } else { boolean isFirstLine = true; for (CharSequence line: lines) { if (isFirstLine) { isFirstLine = false; } else { appendBreak(); } builder.append (line); } } return this; } /** * @see StringBuilder#append (CharSequence,int,int) */ @Override public JComponentHtmlBuilder append (CharSequence chars, int start, int end) throws IOException { builder.append (chars, start, end); return this; } /** * Append a break (newline) to the text * @return this */ public JComponentHtmlBuilder appendBreak() { builder.append ("
"); //$NON-NLS-1$ return this; } /** * Discard all appended text. * @return this */ public JComponentHtmlBuilder clear() { builder.setLength (0); return this; } /** * Creates text that will be rendered with a bold version of the current font. * @param object whose text representation will be rendered. * If object is {@code null}, then {@code "null"} is its representation. * If object implements {@link java.util.Formattable}, then its * {@code formatTo} method is invoked. Otherwise, the representation is * obtained by invoking object's {@code toString} method. * @return text with HTML tags */ public static CharSequence bold (Object object) { return String.format ("%s", object); //$NON-NLS-1$ } /** * Creates text that will be rendered with an italic version of the current font. * @param object whose text representation will be rendered. * If object is {@code null}, then {@code "null"} is its representation. * If object implements {@link java.util.Formattable}, then its * {@code formatTo} method is invoked. Otherwise, the representation is * obtained by invoking object's {@code toString} method. * @return text with HTML tags */ public static CharSequence italic (Object object) { return String.format ("%s", object); //$NON-NLS-1$ } /** * Creates text that will be rendered with an underscored version of the current font. * @param object whose text representation will be rendered. * If object is {@code null}, then {@code "null"} is its representation. * If object implements {@link java.util.Formattable}, then its * {@code formatTo} method is invoked. Otherwise, the representation is * obtained by invoking object's {@code toString} method. * @return text with HTML tags */ public static CharSequence underscore (Object object) { return String.format ("%s", object); //$NON-NLS-1$ } /** * Creates text that will be rendered with a large version of the current font. * @param object whose text representation will be rendered. * If object is {@code null}, then {@code "null"} is its representation. * If object implements {@link java.util.Formattable}, then its * {@code formatTo} method is invoked. Otherwise, the representation is * obtained by invoking object's {@code toString} method. * @return text with HTML tags */ public static CharSequence large (Object object) { return String.format ("%s", object); //$NON-NLS-1$ } /** * Creates text that will be rendered with a small version of the current font. * @param object whose text representation will be rendered. * If object is {@code null}, then {@code "null"} is its representation. * If object implements {@link java.util.Formattable}, then its * {@code formatTo} method is invoked. Otherwise, the representation is * obtained by invoking object's {@code toString} method. * @return text with HTML tags */ public static CharSequence small (Object object) { return String.format ("%s", object); //$NON-NLS-1$ } /** * Creates text that will be rendered with the given color. * @param color one of the {@link Color} enumerators * @param object whose text representation will be rendered. * If object is {@code null}, then {@code "null"} is its representation. * If object implements {@link java.util.Formattable}, then its * {@code formatTo} method is invoked. Otherwise, the representation is * obtained by invoking object's {@code toString} method. * @return text with HTML tags */ public static CharSequence color (Color color, Object object) { return String.format ("%s", //$NON-NLS-1$ color.toString().toLowerCase(), object); } /** * Creates text that will be rendered with the appearance of a hypertext link * (typically underscored and bright blue). * @param object whose text representation will be rendered. * If object is {@code null}, then {@code "null"} is its representation. * If object implements {@link java.util.Formattable}, then its * {@code formatTo} method is invoked. Otherwise, the representation is * obtained by invoking object's {@code toString} method. * @return text with HTML tags */ public static CharSequence anchor (Object object) { return String.format ("%s", object); //$NON-NLS-1$ } /** * Gets a string containing HTML text that can be * passed to a JComponent's setText method. * @return HTML {@link String} * @see javax.swing.JLabel#setText * @see javax.swing.AbstractButton#setText */ public String getText() { /* * Add bracketing tags dynamically (not modifying the builder) * so the same builder can be used multiple times, with * additional methods called after getText() is called. * * Note no tag necessary in JComponent HTML text. */ return String.format ("%s", builder.toString()); //$NON-NLS-1$ } }