Question

I have a question regarding the awt Color class in Java.

I am currently using the class abbreviations such as Color.RED and Color.BLACK. I also have a list of three integers such as the following:

int var1 = 0
int var2 = 0
int var3 = 255

Is there a method to convert these integers into the appropriate Java Color name?

Was it helpful?

Solution

There is no way to do this with a single method in the Java core classes. However, you can fairly easily do this yourself in two ways.

First way

First, create a HashMap of Colors that contains all the colors you want:

HashMap<Color, String> colors = new HashMap<Color, String>();

colors.put(Color.BLACK,            "BLACK");
colors.put(Color.BLUE,             "BLUE");
colors.put(Color.CYAN,             "CYAN");
colors.put(Color.DARK_GRAY,        "DARK_GRAY");
colors.put(Color.GRAY,             "GRAY");
colors.put(Color.GREEN,            "GREEN");
colors.put(Color.LIGHT_GRAY,       "LIGHT_GRAY");
colors.put(Color.MAGENTA,          "MAGENTA");
colors.put(Color.ORANGE,           "ORANGE");
colors.put(Color.PINK,             "PINK");
colors.put(Color.RED,              "RED");
colors.put(Color.WHITE,            "WHITE");
colors.put(new Color(192, 0, 255), "PURPLE");
colors.put(new Color(0xBADA55),    "BADASS_GREEN");
colors.put(new Color(0, 0, 128),   "DARK_BLUE");

Then, create a new Color out of the RGB values you have:

Color color = new Color(var1, var2, var3);

Last, get the value in colors for the key color:

String colorName = colors.get(color);

Second way

This is potentially a less brittle way, but does have issues, and doesn't work as-is. You'll need to catch some exceptions, and maybe handle the case where a field isn't static and you can't just do f.get(null).

Create a new Color out of the RGB values you have:

Color color = new Color(var1, var2, var3);

Then

  1. Get the Class object from the Color class with getClass().
  2. Get the fields from that with getDeclaredFields().
  3. Stream it using Arrays.stream()
  4. Filter it by calling filter(), so it only contains all the enum constants that equal the color you made (there should be either one or zero).
  5. Use toArray() to turn the stream into an array.
  6. Get the first element of that array with [0]. This will throw an ArrayIndexOutOfBoundsException if there isn't a predefined color matching your color.
  7. Get the name of that color with Enum's toString().
String colorName = Arrays.stream(Color.getClass().getDeclaredFields())
                         .filter(f -> f.get(null).equals(color))
                         .toArray()[0]
                         .toString();

OTHER TIPS

There is no set function for this kind of behavior, but you could do something like this:

public static String getColorName(int r, int g, int b) {
    String[] colorNames = new String[] {
            "BLACK",
            "BLUE",
            "GREEN",
            "CYAN",
            "DARK_GRAY",
            "GRAY",
            "LIGHT_GRAY",
            "MAGENTA",
            "ORANGE",
            "PINK",
            "RED",
            "WHITE",
            "YELLOW"
    };
    Color userProvidedColor = new Color(r,g,b);
    Color color;
    Field field;
    for (String colorName : colorNames) {
        try {
            field = Class.forName("java.awt.Color").getField(colorName);
            color = (Color)field.get(null);
            if (color.equals(userProvidedColor)) {
                return colorName; // Or maybe return colorName.toLowerCase() for aesthetics
            }
        } catch (Exception e) {

        }
    }
    Color someOtherCustomDefinedColorMaybePurple = new Color(128,0,128);
    if (someOtherCustomDefinedColorMaybePurple.equals(userProvidedColor)) {
        return "Purple";
    }
    return "Undefined";
}

There are a few options from here as well, maybe you want the nearest color? In which case you could try and resolve the distance somehow (here by distance from each r,g,b coordinate, admittedly not the best method but simple enough for this example, this wiki page has a good discussion on more rigorous methods)

// ...
String minColorName = "";
float minColorDistance = 10000000;
float thisColorDistance = -1;
for (String colorName : colorNames) {
    try {
        field = Class.forName("java.awt.Color").getField(colorName);
        color = (Color)field.get(null);
        thisColorDistance = ( Math.abs(color.red - userProvidedColor.red) + Math.abs(color.green - userProvidedColor.green) + Math.abs(color.blue - userProvidedColor.blue) );
        if (thisColorDistance < minColorDistance) {
            minColorName = colorName;
            minColorDistance = thisColorDistance;
        }
    } catch (Exception e) {
        // exception that should only be raised in the case color name is not defined, which shouldnt happen
    }
}
if (minColorName.length > 0) {
    return minColorName;
}
// Tests on other custom defined colors

This should outline how you would be able to compare to the built in colors from the Color library. You could use a Map to expand the functionality further to allow for you to define as many custom colors as you like (Something @TheGuywithTheHat suggests as well) which gives you more control over the return names of matched colors, and allows for you to go by more colors than just the predefined ones:

HashMap<String,Color> colorMap = new HashMap<String,Color>();

colorMap.put("Red",Color.RED);
colorMap.put("Purple",new Color(128,0,128));
colorMap.put("Some crazy name for a color", new Color(50,199,173));
// etc ...

String colorName;
Color color;
for (Map.Entry<String, Color> entry : colorMap.entrySet()) {
    colorName = entry.getKey();
    color= entry.getValue();
    // Testing against users color
}

As far as i know, we don't have any such library to directly access the colors from the Constants.

But we can manage do it using Hex Color Library in Java.

References :

  1. Hex

  2. Color Class

Without any helping libraries I would say: No. Especially because not every RGB-Color has a specific name. However, you could of course build an own function, which tries to match some of the available colors and deliver something like "Unknown" if there is no match.

The matching attempt could theoretically be done using the Java reflection API...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top