【问题标题】:Color Class in JavaJava中的颜色类
【发布时间】:2014-06-14 07:14:29
【问题描述】:

我对 Java 中的 awt Color 类有疑问。

我目前正在使用诸如Color.REDColor.BLACK 之类的类缩写。我还有一个包含三个整数的列表,如下所示:

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

有没有办法将这些整数转换成适当的 Java Color 名称?

【问题讨论】:

  • 您是要使用这 3 个变量创建颜色(因为有一个 Color 构造函数可以执行此操作),还是要获取相关的缩写(在您的示例中为 Color.BLUE)?
  • 颜色没有名字。
  • Check Documentation 正如 AntonH 所说,如果你只想创建一个新颜色,你可以这样做Color(float r, float g, float b)
  • 或者,既然你指的是ints,Color (int r, int g, int b);

标签: java awt


【解决方案1】:

在 Java 核心类中没有办法用单一方法来做到这一点。但是,您可以通过两种方式自己轻松地做到这一点。

第一种方式

首先,创建一个Colors 中的HashMap,其中包含您想要的所有颜色:

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

然后,从您拥有的 RGB 值中创建一个新的Color

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

最后,get colors 中的值作为键 color

String colorName = colors.get(color);

第二种方式

这可能是一种不太脆弱的方式,但确实存在问题,并且无法按原样工作。您需要捕获一些异常,并且可能需要处理字段不是静态且您不能只执行f.get(null) 的情况。

从您拥有的 RGB 值中创建一个新的Color

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

然后

  1. 使用getClass()Color 类中获取Class 对象。
  2. 使用getDeclaredFields() 从中获取字段。
  3. 使用Arrays.stream() 流式传输
  4. 通过调用filter()对其进行过滤,因此它只包含与您制作的颜色相同的所有枚举常量(应该是一或零)。
  5. 使用toArray() 将流转换为数组。
  6. 使用[0] 获取该数组的第一个元素。如果没有与您的颜色匹配的预定义颜色,这将引发 ArrayIndexOutOfBoundsException
  7. 使用EnumtoString() 获取该颜色的名称。
String colorName = Arrays.stream(Color.getClass().getDeclaredFields())
                         .filter(f -> f.get(null).equals(color))
                         .toArray()[0]
                         .toString();

【讨论】:

  • Color.class.getEnumConstants() 返回null 因为Color 不是枚举:-( 必须调整方法来迭代静态最终常量。
  • @JensBannmann 好点,感谢您接听。我已经更新了我的答案。
【解决方案2】:

这种行为没有设置函数,但你可以这样做:

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

这里也有一些选择,也许您想要最接近的颜色?在这种情况下,您可以尝试以某种方式解决距离问题(这里通过每个 r、g、b 坐标的距离,诚然不是最好的方法,但对于这个例子来说足够简单,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

这应该概述您将如何与Color 库中的内置颜色进行比较。您可以使用Map 进一步扩展功能,允许您定义任意数量的自定义颜色(@TheGuywithTheHat 也建议),这使您可以更好地控制匹配颜色的返回名称,并允许您可以选择更多颜色,而不仅仅是预定义的颜色:

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
}

【讨论】:

    【解决方案3】:

    据我所知,我们没有任何此类库可以直接访问常量中的颜色

    但我们可以使用 Java 中的十六进制颜色库来管理。

    参考资料:

    1. Hex

    2. Color Class

    【讨论】:

      【解决方案4】:

      如果没有任何帮助库,我会说:不。尤其是因为不是每个 RGB 颜色都有一个特定的名称。但是,您当然可以构建一个自己的函数,它会尝试匹配一些可用的颜色,并在没有匹配的情况下提供类似“未知”的内容。

      理论上可以使用 Java 反射 API 来完成匹配尝试...

      【讨论】:

      • 您也可以尝试解析为最接近的可用预定义颜色,但我同意您必须自己实现。
      猜你喜欢
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 2023-03-26
      • 2019-05-03
      • 2021-12-27
      • 1970-01-01
      • 2014-03-27
      • 2020-06-09
      相关资源
      最近更新 更多