Как получить шестнадцатеричный формат из имен цветов в Java? - PullRequest
0 голосов
/ 21 апреля 2019

У меня есть названия цветов, такие как Белый, Красный, Синий и т. Д., И я пытаюсь получить соответствующее шестнадцатеричное представление.Например, если я передаю аргумент, такой как White, он должен вернуть #FFFFFF.

Хотя это кажется простым, в Java нет прямого решения.Ниже приведен код, который я пробовал.

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
}

Приведенный выше код работает нормально, но я ищу чистое и элегантное решение, если оно вообще доступно, по крайней мере, в последней версии Java.

Ответы [ 2 ]

2 голосов
/ 23 апреля 2019

Вы должны использовать строку формата "#%06X" вместо "%06x#". Во-первых, он помещает символ # в нужную вам позицию, во-вторых, он генерирует шестнадцатеричную строку в верхнем регистре, устраняя необходимость вызова toUpperCase() для результата.

Но сколько экономит ваша рефлексивная операция по сравнению с явной картой значений? Когда я бегу по всем полям Color, например через

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));

Я получаю

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");

что не так уж и велико. Поэтому, когда я копирую этот вывод в новый код, такой как

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(), "");
}

результат прост и без размышлений. Обслуживание будет независимым от отражающего кода, который создал эту версию, так как проще добавить новую константу на карту, чем добавить новую константу в класс java.awt.Color (для повторного запуска отражающего кода).

Единственная альтернатива с большей гибкостью - использовать файл properties , который позволяет обновлять карту без перекомпиляции приложения. Вместо этого легко адаптировать приведенный выше код для создания файла свойств, но, с другой стороны, в Интернете достаточно готовых к использованию файлов с еще большим количеством цветов. Например, вы можете скопировать веб-цвета на основе VGA непосредственно из w3.org , тогда как этот расширенный список потребует расширенного поиска и замены в формате свойств.

0 голосов
/ 23 апреля 2019

Используя Color из OpenFX, каждый избавляется от метода для всех веб-цветов.

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

Результат:

0x87cdebff

Они существуют также как константные поля, поэтому можно использовать автозаполнение,Но мне нравится автодополнение в редакторе CSS / HTML.


Это отдельная зависимость, библиотека.Но начиная с java 9 ожидается модульная инфраструктура, и OpenFX, ранее JavaFX, не вызывал проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...