Add ComponentBuilder + make events final

An example of ComponentBuilder usage can be found at CommandAlertRaw
This commit is contained in:
Thinkofdeath 2013-12-10 11:50:34 +00:00
parent bc746a546f
commit 5d68b422e5
8 changed files with 199 additions and 40 deletions

View File

@ -81,6 +81,8 @@ public abstract class BaseComponent
setUnderlined( old.isUnderlined() );
setStrikethrough( old.isStrikethroughRaw() );
setObfuscated( old.isObfuscatedRaw() );
setClickEvent( old.getClickEvent() );
setHoverEvent( old.getHoverEvent() );
}
/**

View File

@ -7,41 +7,39 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ClickEvent
final public class ClickEvent
{
/**
* The type of action to preform on click
*/
private Action action;
private final Action action;
/**
* Depends on action
* @see net.md_5.bungee.api.chat.ClickEvent.Action
*/
private String value;
private final String value;
public enum Action
{
/**
* Open a url at the path given by
* {@link net.md_5.bungee.api.chat.ClickEvent#setValue(String)}
* {@link net.md_5.bungee.api.chat.ClickEvent#getValue()}
*/
OPEN_URL,
/**
* Open a file at the path given by
* {@link net.md_5.bungee.api.chat.ClickEvent#setValue(String)}
* {@link net.md_5.bungee.api.chat.ClickEvent#getValue()}
*/
OPEN_FILE,
/**
* Run the command given by
* {@link net.md_5.bungee.api.chat.ClickEvent#setValue(String)}
* {@link net.md_5.bungee.api.chat.ClickEvent#getValue()}
*/
RUN_COMMAND,
/**
* Inserts the string given by
* {@link net.md_5.bungee.api.chat.ClickEvent#setValue(String)}
* {@link net.md_5.bungee.api.chat.ClickEvent#getValue()}
* into the players text box
*/
SUGGEST_COMMAND

View File

@ -0,0 +1,157 @@
package net.md_5.bungee.api.chat;
import lombok.NoArgsConstructor;
import net.md_5.bungee.api.ChatColor;
import java.util.ArrayList;
import java.util.List;
/**
* 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
*/
public class ComponentBuilder
{
private TextComponent current;
private List<BaseComponent> parts = new ArrayList<>();
/**
* 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)
{
parts.add( current );
current = new TextComponent( current );
current.setText( text );
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 pat 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 click event for the current part.
* @param clickEvent
* @return
*/
public ComponentBuilder event(ClickEvent clickEvent)
{
current.setClickEvent( clickEvent );
return this;
}
public ComponentBuilder event(HoverEvent hoverEvent)
{
current.setHoverEvent( hoverEvent );
return this;
}
/**
* Returns the components needed to display the message
* created by this builder
* @return the created components
*/
public BaseComponent[] create()
{
parts.add( current );
return parts.toArray( new BaseComponent[parts.size()] );
}
}

View File

@ -5,14 +5,12 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@NoArgsConstructor
@Getter
@Setter
@AllArgsConstructor
public class HoverEvent
final public class HoverEvent
{
private Action action;
private BaseComponent value;
private final Action action;
private final BaseComponent[] value;
public enum Action
{

View File

@ -94,19 +94,10 @@ public class TextComponent extends BaseComponent
TextComponent old = component;
component = new TextComponent( old );
ClickEvent clickEvent = new ClickEvent();
clickEvent.setAction( ClickEvent.Action.OPEN_URL );
String urlString = message.substring( i, pos );
if ( urlString.startsWith( "http" ) )
{
component.setText( urlString );
clickEvent.setValue( urlString );
} else
{
component.setText( urlString );
clickEvent.setValue( "http://" + urlString );
}
component.setClickEvent( clickEvent );
component.setText( urlString );
component.setClickEvent( new ClickEvent( ClickEvent.Action.OPEN_URL,
urlString.startsWith( "http" ) ? urlString : "http://" + urlString ) );
components.add( component );
i += pos - i - 1;
component = old;

View File

@ -55,11 +55,13 @@ public class BaseComponentSerializer
if ( object.has( "hoverEvent" ) )
{
JsonObject event = object.getAsJsonObject( "hoverEvent" );
HoverEvent hoverEvent = new HoverEvent();
hoverEvent.setAction( HoverEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase() ) );
BaseComponent res = context.deserialize( event.get( "value" ), BaseComponent.class );
hoverEvent.setValue( res );
component.setHoverEvent( hoverEvent );
BaseComponent[] res;
if (event.get("value").isJsonArray()) {
res = context.deserialize( event.get( "value" ), BaseComponent[].class );
} else {
res = new BaseComponent[]{context.<BaseComponent>deserialize( event.get( "value" ), BaseComponent.class )};
}
component.setHoverEvent( new HoverEvent( HoverEvent.Action.valueOf( event.get( "action" ).getAsString().toUpperCase() ), res ) );
}
}

View File

@ -4,6 +4,7 @@ import com.google.common.base.Joiner;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.plugin.Command;
@ -34,15 +35,12 @@ public class CommandAlertRaw extends Command
ProxyServer.getInstance().broadcast( ComponentSerializer.parse( message ) );
} catch ( Exception e )
{
TextComponent error = new TextComponent( "An error occurred while parsing your message. (Hover for details)" );
error.setColor( ChatColor.RED );
error.setUnderlined( true );
TextComponent errorMessage = new TextComponent( e.getMessage() );
errorMessage.setColor( ChatColor.RED );
error.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, errorMessage ) );
sender.sendMessage( error );
sender.sendMessage(
new ComponentBuilder( "An error occured while parsing your message. (Hover for details)" ).
color( ChatColor.RED ).underlined( true ).
event( new HoverEvent( HoverEvent.Action.SHOW_TEXT,
new ComponentBuilder( e.getMessage() ).color( ChatColor.RED ).create() ) ).
create() );
}
}
}

View File

@ -3,6 +3,7 @@ package net.md_5.bungee.chat;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
import org.junit.Assert;
@ -66,4 +67,16 @@ public class ComponentsTest
Assert.assertEquals( ChatColor.WHITE + "Page " + ChatColor.WHITE + "5" + ChatColor.WHITE + " of " + ChatColor.WHITE + "50", positional.toLegacyText() );
}
@Test
public void testBuilder()
{
BaseComponent[] components = new ComponentBuilder( "Hello " ).color( ChatColor.RED ).
append( "World" ).bold( true ).color( ChatColor.BLUE ).
append( "!" ).color( ChatColor.YELLOW ).create();
Assert.assertEquals( "Hello World!", BaseComponent.toPlainText( components ) );
Assert.assertEquals( ChatColor.RED + "Hello " + ChatColor.BLUE + ChatColor.BOLD +
"World" + ChatColor.YELLOW + ChatColor.BOLD + "!", BaseComponent.toLegacyText( components ) );
}
}