package net.md_5.bungee.api.chat; import net.md_5.bungee.api.ChatColor; import java.util.ArrayList; import java.util.List; /** * <p> * ComponentBuilder simplifies creating basic messages by allowing the use of a * chainable builder. * </p> * <pre> * new ComponentBuilder("Hello ").color(ChatColor.RED). * append("World").color(ChatColor.BLUE). append("!").bold(true).create(); * </pre> * <p> * All methods (excluding {@link #append(String)} and {@link #create()} work on * the last part appended to the builder, so in the example above "Hello " would * be {@link net.md_5.bungee.api.ChatColor#RED} and "World" would be * {@link net.md_5.bungee.api.ChatColor#BLUE} but "!" would be bold and * {@link net.md_5.bungee.api.ChatColor#BLUE} because append copies the previous * part's formatting * </p> */ public class ComponentBuilder { private TextComponent current; private final List<BaseComponent> parts = new ArrayList<BaseComponent>(); /** * Creates a ComponentBuilder from the other given ComponentBuilder to clone * it. * * @param original the original for the new ComponentBuilder. */ public ComponentBuilder(ComponentBuilder original) { current = new TextComponent( original.current ); for ( BaseComponent baseComponent : original.parts ) { parts.add( baseComponent.duplicate() ); } } /** * Creates a ComponentBuilder with the given text as the first part. * * @param text the first text element */ public ComponentBuilder(String text) { current = new TextComponent( text ); } /** * Appends the text to the builder and makes it the current target for * formatting. The text will have all the formatting from the previous part. * * @param text the text to append * @return this ComponentBuilder for chaining */ public ComponentBuilder append(String text) { return append( text, FormatRetention.ALL ); } /** * Appends the text to the builder and makes it the current target for * formatting. You can specify the amount of formatting retained. * * @param text the text to append * @param retention the formatting to retain * @return this ComponentBuilder for chaining */ public ComponentBuilder append(String text, FormatRetention retention) { parts.add( current ); current = new TextComponent( current ); current.setText( text ); retain( retention ); return this; } /** * Sets the color of the current part. * * @param color the new color * @return this ComponentBuilder for chaining */ public ComponentBuilder color(ChatColor color) { current.setColor( color ); return this; } /** * Sets whether the current part is bold. * * @param bold whether this part is bold * @return this ComponentBuilder for chaining */ public ComponentBuilder bold(boolean bold) { current.setBold( bold ); return this; } /** * Sets whether the current part is italic. * * @param italic whether this part is italic * @return this ComponentBuilder for chaining */ public ComponentBuilder italic(boolean italic) { current.setItalic( italic ); return this; } /** * Sets whether the current part is underlined. * * @param underlined whether this part is underlined * @return this ComponentBuilder for chaining */ public ComponentBuilder underlined(boolean underlined) { current.setUnderlined( underlined ); return this; } /** * Sets whether the current part is strikethrough. * * @param strikethrough whether this part is strikethrough * @return this ComponentBuilder for chaining */ public ComponentBuilder strikethrough(boolean strikethrough) { current.setStrikethrough( strikethrough ); return this; } /** * Sets whether the current part is obfuscated. * * @param obfuscated whether this part is obfuscated * @return this ComponentBuilder for chaining */ public ComponentBuilder obfuscated(boolean obfuscated) { current.setObfuscated( obfuscated ); return this; } /** * Sets the insertion text for the current part. * * @param insertion the insertion text * @return this ComponentBuilder for chaining */ public ComponentBuilder insertion(String insertion) { current.setInsertion( insertion ); return this; } /** * Sets the click event for the current part. * * @param clickEvent the click event * @return this ComponentBuilder for chaining */ public ComponentBuilder event(ClickEvent clickEvent) { current.setClickEvent( clickEvent ); return this; } /** * Sets the hover event for the current part. * * @param hoverEvent the hover event * @return this ComponentBuilder for chaining */ public ComponentBuilder event(HoverEvent hoverEvent) { current.setHoverEvent( hoverEvent ); return this; } /** * Sets the current part back to normal settings. Only text is kept. * * @return this ComponentBuilder for chaining */ public ComponentBuilder reset() { return retain( FormatRetention.NONE ); } /** * Retains only the specified formatting. Text is not modified. * * @param retention the formatting to retain * @return this ComponentBuilder for chaining */ public ComponentBuilder retain(FormatRetention retention) { BaseComponent previous = current; switch ( retention ) { case NONE: current = new TextComponent( current.getText() ); break; case ALL: // No changes are required break; case EVENTS: current = new TextComponent( current.getText() ); current.setInsertion( previous.getInsertion() ); current.setClickEvent( previous.getClickEvent() ); current.setHoverEvent( previous.getHoverEvent() ); break; case FORMATTING: current.setClickEvent( null ); current.setHoverEvent( null ); break; } return this; } /** * Returns the components needed to display the message created by this * builder. * * @return the created components */ public BaseComponent[] create() { BaseComponent[] result = parts.toArray( new BaseComponent[ parts.size() + 1 ] ); result[parts.size()] = current; return result; } public static enum FormatRetention { /** * Specify that we do not want to retain anything from the previous * component. */ NONE, /** * Specify that we want the formatting retained from the previous * component. */ FORMATTING, /** * Specify that we want the events retained from the previous component. */ EVENTS, /** * Specify that we want to retain everything from the previous * component. */ ALL } }