简体   繁体   中英

How to get the hexadecimal format from color names in Java?

I have got color names such as White, Red, Blue, etc., and I'm trying to get its corresponding hexadecimal representation. For example, if I pass an argument such as White it should return #FFFFFF .

Although it seems simple, there's no straight solution in Java. Following is the code I have tried.

private String getHexaColor (String basicColor /* White */) {
    java.awt.Color color;
    try {
        java.lang.reflect.Field field = Class.forName("java.awt.Color").getField(basicColor.toLowerCase());
        color = (Color) field.get(null);
    } catch (Exception e) {
        color = null; 
    }

    return (color != null) ? String.format("%06x#", color.getRGB() & 0x00FFFFFF).toUpperCase() : ""; //return #FFFFFF
}

Above code is working fine, but I'm looking for a clean and elegant solution if at all available at least in the latest version of Java.

You should use the format string "#%06X" rather than "%06x#" . First, it places the # character at the position you actually want, second, it generates an upper case hexadecimal string, removing the need to call toUpperCase() on the result.

But how much does your reflective operation save, compared to an explicit map of values? When I run over all fields of Color , eg via

final int constant = Modifier.STATIC | Modifier.FINAL;
Map<String,Integer> m = new HashMap<>();
for(Field f: Color.class.getFields()) try {
    if((f.getModifiers() & constant) == constant && f.getType() == Color.class)
        m.put(f.getName().toLowerCase().replace('_', ' '),
            ((Color)f.get(null)).getRGB() & 0x00FFFFFF);
} catch(ReflectiveOperationException ex) {
    throw new AssertionError(ex);
}
m.forEach((name,rgb) -> System.out.printf("map.put(\"%s\", \"#%06X\");%n", name, rgb));

I get

map.put("magenta", "#FF00FF");
map.put("pink", "#FFAFAF");
map.put("green", "#00FF00");
map.put("black", "#000000");
map.put("yellow", "#FFFF00");
map.put("cyan", "#00FFFF");
map.put("dark gray", "#404040");
map.put("red", "#FF0000");
map.put("orange", "#FFC800");
map.put("gray", "#808080");
map.put("white", "#FFFFFF");
map.put("blue", "#0000FF");
map.put("darkgray", "#404040");
map.put("light gray", "#C0C0C0");
map.put("lightgray", "#C0C0C0");

which is not that big. So, when I copy that output into a new code like

static final Map<String,String> COLOR_CODES;
static {
    Map<String,String> map = new HashMap<>();
    map.put("magenta", "#FF00FF");
    map.put("pink", "#FFAFAF");
    map.put("green", "#00FF00");
    map.put("black", "#000000");
    map.put("yellow", "#FFFF00");
    map.put("cyan", "#00FFFF");
    map.put("dark gray", "#404040");
    map.put("red", "#FF0000");
    map.put("orange", "#FFC800");
    map.put("gray", "#808080");
    map.put("white", "#FFFFFF");
    map.put("blue", "#0000FF");
    map.put("darkgray", "#404040");
    map.put("light gray", "#C0C0C0");
    map.put("lightgray", "#C0C0C0");
    COLOR_CODES = Collections.unmodifiableMap(map);
}
static String getHexaColor(String colorName) {
    return COLOR_CODES.getOrDefault(colorName.toLowerCase(), "");
}

the result is simple and reflection free. Maintenance would be independent of the reflective code that produced this version, as it is simpler to add a new constant to the map than to add a new constant to the java.awt.Color class (to re-run the reflective code).

The only alternative with more flexibility would be to use a properties file, which allows to update the map without recompiling the application. It's easy to adapt the code above to generate a properties file instead, but on the other hand, there are enough ready-to-use files on the internet with even more colors. Eg, you can copy the VGA based web colors directly from w3.org , whereas this extended list would require an advanced search-and-replace to be brought into the properties format.

Using Color from OpenFX, one disposes over a method for all web colors.

import javafx.scene.paint.Color;
Color color = Color.web("skyblue");

Result:

0x87cdebff

These exist also as constant fields, so one might use autocompletion. But I like the autocompletion in a CSS/HTML editor.


This is a separate dependency, library. But as of java 9 a modular infrastructure is to be expected, and OpenFX, formerly JavaFX, is unproblematic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM