ChatColor help

Discussion in 'Plugin Development' started by Dragoloy, Jul 8, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    Dragoloy

    Hello developers,

    I'm developing a color changing plugin, and one of my commands should list all of the available colors. I have the following code inside of the command:

    Code:
    public ChatColor[] acceptableColors = {ChatColor.AQUA, ChatColor.BLACK, ChatColor.BLUE, ChatColor.GOLD, ChatColor.DARK_AQUA, ChatColor.DARK_BLUE, ChatColor.DARK_GREEN, ChatColor.DARK_PURPLE, ChatColor.DARK_RED, ChatColor.GOLD, ChatColor.GREEN, ChatColor.ITALIC, ChatColor.LIGHT_PURPLE, ChatColor.MAGIC, ChatColor.RED, ChatColor.RESET, ChatColor.STRIKETHROUGH, ChatColor.UNDERLINE, ChatColor.WHITE, ChatColor.YELLOW};
    player.sendMessage(ChatColor.BLUE + "Available Colors:");
                    for (ChatColor color : acceptableColors) {
                        player.sendMessage(color + "" + color.toString());
                    }
    When I run the command, only "Available Colors:" appears, with a bunch of blank lines underneath it.

    Is there a way to get this to work as I want it to?

    As a side question, is there a way of constructing a chat color from a string (such as "GOLD")?

    Thanks in advance.
     
  2. Offline

    Zombie_Striker

    @Dragoloy
    That is because you can loop through collections, but you can't loop through arrays. Either convert your array to a collection, or use a For int loop to loop through all the indexes.
     
    Dragoloy likes this.
  3. Offline

    Dragoloy

    @Zombie_Striker
    Thanks. I'll try that.

    I'm still confused about my side questions though, in case anyone knows the answer:
    Is there a way of constructing a chat color from a string (such as "GOLD")?
     
  4. Offline

    SuperSniper

    Here is the method for "constructing a chatcolor from a string" :p

    Code:
        public static ChatColor getColor(String color) {
            switch (color) {
            case "black":
                return ChatColor.BLACK;
            case "dark_blue":
                return ChatColor.DARK_BLUE;
            case "dark_green":
                return ChatColor.DARK_GREEN;
            case "aqua":
                return ChatColor.AQUA;
            case "dark_red":
                return ChatColor.DARK_RED;
            case "purple":
                return ChatColor.DARK_PURPLE;
            case "gold":
                return ChatColor.GOLD;
            case "gray":
                return ChatColor.GRAY;
            case "dark_gray":
                return ChatColor.DARK_GRAY;
            case "blue":
                return ChatColor.BLUE;
            case "green":
                return ChatColor.GREEN;
            case "dark_aqua":
                return ChatColor.DARK_AQUA;
            case "red":
                return ChatColor.RED;
            case "pink":
                return ChatColor.LIGHT_PURPLE;
            case "yellow":
                return ChatColor.YELLOW;
            case "white":
                return ChatColor.WHITE;
            case "bold":
                return ChatColor.BOLD;
            default:
                return ChatColor.WHITE;
            }
        }
    
     
  5. Offline

    MCKrypto14

    Um that's not true at all. You can use for loops on arrays.

    And also the ChatColor.toString() method returns the color code for the color, not the actual name of the color. So what you want to use is the ChatColor.name().

    Is is what you want:

    Code:
    for (final ChatColor color: acceptableColors) {
         player.sendMessage(color.toString() + color.name().replace('_', ' '));
    }
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jul 9, 2016
  6. Offline

    I Al Istannen

    @Dragoloy
    If available colors are all, ChatColor.values() shortens the code by a lot. Haven't checked, just throwing it in here :p

    @Zombie_Striker
    You can loop through every object implementing "java.lang.Iterable" OR through arrays (dunno if they implement it or an exception was made for them) with enhanced for loops.

    @SuperSniper
    What happened to
    Code:
    return ChatColor.valueOf(name.toUpperCase());
    It is an enum after all. Just beware of the IllegalArgumentException that can happen if the constant is not found.


    @MCKrypto14
    May want to write that a bit nicer, and convert it to lower case "dark_brown" or edit it a bit more "Dark Brown". This is purely cosmetic and depends on your language. I would prefer the "Dark Brown" one :p

    The final there is also unneeded and clutters it a bit imho.

    And the + "" + is useless. Just leave it out. You can even leave out the "toString()" after the color, as it will be automatically called to concat it with the String "color.name()".

    And lastly, edit your post instead of double posting (next time). It is enforced a bit too (imho) strictly here normally though.
     
    bwfcwalshy likes this.
  7. Offline

    MCKrypto14

    actually using the .toString() method and using the final keyword both save the compiler time and dont need to call it itself. Using a string builder would be even faster, though
     
  8. Offline

    I Al Istannen

    @MCKrypto14
    The time saved from the "final", if any, is so neglegible.

    The time saved by the toString. Could you show me some source for that?

    You are concating two strings, don't think the StringBuilder saves much there.
     
  9. Offline

    MCKrypto14

  10. Offline

    I Al Istannen

    @MCKrypto14
    Code:
    package me.ialistannen.toy_around;
    
    import org.bukkit.ChatColor;
    import org.junit.Test;
    
    
    @SuppressWarnings("javadoc")
    public class TestToString {
    
        @Test
        public void test() {
            ChatColor color = ChatColor.RED;
            System.out.println(color + color.name());
        }
    
        @Test
        public void testToString() {
            ChatColor color = ChatColor.RED;
            System.out.println(color.toString() + color.name());
        }
    
        @Test
        public void testBuilder() {
            ChatColor color = ChatColor.RED;
            System.out.println(new StringBuilder(color.toString()).append(color.name()).toString());
        }
    
    }
    Timings.png
    Obviously not the best timing, but it are some. It stays roughly the same if you increase the number of iterations. I don't know if JUnit warms up the VM first and lets the HotSpot compiler do it's thing, but the timings shouldn't change that much.

    And the thing you quoted doesn't argue with what I said. It just says that the compiler itself changes concatening with + to a StringBuilder, where it can.

    But this is getting offtopic, feel free to message me and we can continue this discussion via PM. I just want to clarify right now that I do not want to offend you or anything. I am also willing to change my opinion, if I am wrong.
     
  11. Offline

    Dragoloy

    Thanks for the help.

    Does ChatColor.Values() return all of the ChatColor names?
     
  12. Offline

    I Al Istannen

    @Dragoloy
    Try it. And values is written with an lowercase letter.

    But yes, they do:
    (source)
     
  13. Offline

    Dragoloy

    Thanks everyone. I got it to work. I didn't need to convert the array to a collection though. I used ChatColor.name(), and converted strings to chatcolors using ChatColor.ValueOf(string), in case anyone needs help in the future.
     
  14. Offline

    I Al Istannen

    @Dragoloy
    Nice you sorted it out! Good job :)

    Have a nice day and good luck with the rest of the plugin ;)
     
    Dragoloy likes this.
Thread Status:
Not open for further replies.

Share This Page