[SOLVED] Interface vs Enum vs any other better solution?

Hello folks! I was a few days ago reading random topics here on the site, and I came across this, where I felt interested to create a .jar file with a compilation of colors to use in my sketches.
My question is, I have already created a list of 854 colors that you can find here, and I wanted to know if is there any way to show the contents of that list as if someone did a print(Palette.list()). The color list is arranged as constants inside an interface, so the user just needs to invoke the interface and choose the color, like fill(Palette.OLIVE_DRAB), but I know I can not write methods that return me this constants as values. I do not know how Enums work, maybe it’s a good alternative? I wanted to avoid using Classes with arrays because it would be very impractical to have things like Palette palette = new Palette (); palette.getColor ("olive_drab").

1 Like

Here is a smaller version of the Palette interface i created, so that you can visualize it:

public interface Palette {
    static final int
            BLACK                   = 0xff000000,
            DIM_GRAY                = 0xff696969,
            GRAY                    = 0xff808080,
            DARK_GRAY               = 0xffA9A9A9,
            SILVER                  = 0xffC0C0C0,
            LIGHT_GRAY              = 0xffD3D3D3,
            GAINSBORO               = 0xffDCDCDC,
            WHITE_SMOKE             = 0xffF5F5F5,
            WHITE                   = 0xffFFFFFF,
            SNOW                    = 0xffFFFAFA,
            AZURE                   = 0xffF0FFFF,
            IVORY                   = 0xffFFFFF0,
}
1 Like

If you use actual Java enums you can get a list of all the values. Have a read of this which came top of search and even covers colours! :smile:

https://www.geeksforgeeks.org/enum-in-java/

However you’ll have to find a way to store the underlying colour value that Processing wants if you need to pass it in to fill()

1 Like

There are many approaches you could take.

You could use a HashMap of color names to color values. Something like:

HashMap<String, Integer> colorMap = new HashMap<>();
colorMap.put("BLACK", 0xff000000);
colorMap.put("DIM_GRAY", 0xff696969);
// ...
fill(colorMap.get("BLACK"));

You could further encapsulate this in a class, maybe using a static method to give you colors.

You might also look into using reflection to get the variable names, but that’s usually a sign that you should think about refactoring your approach.

4 Likes

Thanks @Kevin! After your advices i started a long study on Java Reflections and guess what? I’m in love with the power this java feature offers. So here is my humble approach using Reflection to get EXACTLY what i wanted in this post. I am still learnig this tecnique so please, if you think i am doing it wrongly, let me know.

package overmind;
import java.lang.reflect.Field;

public abstract class Palette {
    public static final int
            BLACK                   = 0xff000000,
            DIM_GRAY                = 0xff696969,
            GRAY                    = 0xff808080,
            DARK_GRAY               = 0xffA9A9A9,
            SILVER                  = 0xffC0C0C0,
            LIGHT_GRAY              = 0xffD3D3D3,
            GAINSBORO               = 0xffDCDCDC,
            WHITE_SMOKE             = 0xffF5F5F5,
            WHITE                   = 0xffFFFFFF,
            SNOW                    = 0xffFFFAFA,
            AZURE                   = 0xffF0FFFF,
            IVORY                   = 0xffFFFFF0;

public static String[] list() {
    String[] colorNames = null;
    try {
      Class thisClass = Class.forName("overmind.Palette");
      Field[] fields = thisClass.getDeclaredFields();
      colorNames = new String[fields.length];

      for (int i = 0; i < fields.length; i++)
        colorNames[i] = fields[i].getName();
    }
    catch(ClassNotFoundException | SecurityException e) {
      System.err.println(e);
    }
    return colorNames;
  }

  public static int[] values() {
    int[] colorValues = new int[list().length];
    try {
      Class thisClass = Class.forName("overmind.Palette");
      Field[] fields = thisClass.getDeclaredFields();

      for (int i = 0; i < fields.length; i++) 
        colorValues[i] = fields[i].getInt(thisClass);
    }
    catch(ClassNotFoundException | IllegalAccessException | IllegalArgumentException | SecurityException e) {
      System.err.println(e);
    }
    return colorValues;
  }
}

As you mentioned, i had to refactor my code and change it from Interface to class. Because of that, i lost the ability to “implement” my palette as i would do with an interface, so i always need to call the Palette class first in order to choose some color. But that’s fine though. I also put my Palette class as an abstract class so that i could mimic an interface (to prevent instatiation) and only use fields and methods in a static way (as you also mentioned).

1 Like

If anyone is interested in installing the Palette, which contains 855 colors, such as a library, here is the github repo. Just download it and paste into the “library” folder inside your Sketchbook :wink:

1 Like