Mega Code Archive

 
Categories / Java / 2D Graphics GUI
 

Utility for checking colors given either hexa or natural language string descriptions

import java.awt.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; /**  * Utility for checking colors given either hexa or "natural language" string descriptions.  * <p>For all assertEquals/equals methods, the "expected" parameter can be either:  * <ul>  * <li>A <code>Color</code> object specifying the exact color</li>  * <li>A <code>String</code> object containing the hexadecimal description of the exact color</li>  * <li>A <code>String</code> object containing the name of a color for an approximate comparison.  * The authorized names are those of the predefined Color objects defined in the Java  * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Color.html">Color</a> class.</li>  * </ul>  * </p>  *  * @see <a href="http://www.uispec4j.org/usingcolors.html">Using colors</a>  */ public final class ColorUtils {   private static final Map<String, Color> nameToColorMap = buildNameToColorMap();   static final String UNEXPECTED_COLOR_CLASS = "Expected color should be an instance of Color or String";   public static boolean equals(Object expectedColor, Color actual) {     if (expectedColor instanceof Color) {       return expectedColor.equals(actual);     }     else if (expectedColor instanceof String) {       return equals((String)expectedColor, actual);     }     throw new IllegalArgumentException(UNEXPECTED_COLOR_CLASS);   }   public static boolean equals(String expectedColor, Color actual) {     Color foundColor = nameToColorMap.get(expectedColor.toUpperCase());     if (foundColor != null) {       return equals(foundColor, actual, true);     }     try {       foundColor = getColor(expectedColor);       return equals(foundColor, actual, false);     }     catch (NumberFormatException e) {       throw new IllegalArgumentException("'" + expectedColor + "' does not seem to be a color");     }   }   public static Color getColor(String hexaString) {     return new Color(Integer.parseInt(hexaString, 16));   }   /**    * Returns a normalized string description given a Color or another String description    */   public static String getColorDescription(Object color) {     if (color instanceof Color) {       return getColorDescription((Color)color);     }     else if (color instanceof String) {       return getColorDescription((String)color);     }     throw new IllegalArgumentException(UNEXPECTED_COLOR_CLASS);   }   /**    * Returns a description string for a given Color object    */   public static String getColorDescription(Color color) {     return toHexString(color).toUpperCase();   }   /**    * Normalizes a given color description string    */   public static String getColorDescription(String color) {     return color.toUpperCase();   }   private static boolean equals(Color expected, Color actual, boolean matchBySimilarity) {     if (matchBySimilarity) {       return computeHSBDistance(expected, actual) < 0.9;     }     else {       return expected.equals(actual);     }   }   private static Color getColor(Object input) {     if (input instanceof Color) {       return (Color)input;     }     else if (input instanceof String) {       Color namedColor = nameToColorMap.get(((String)input).toUpperCase());       if (namedColor != null) {         return namedColor;       }       return getColor((String)input);     }     throw new IllegalArgumentException(UNEXPECTED_COLOR_CLASS);   }   private static double computeHSBDistance(Color expected, Color actual) {     float[] expectedHSB = toHSB(expected);     float[] actualHSB = toHSB(actual);     return Math.sqrt(Math.pow((expectedHSB[0] - actualHSB[0]) * 20, 2)                      + Math.pow(expectedHSB[1] - actualHSB[1], 2)                      + Math.pow((expectedHSB[2] - actualHSB[2]) * 2, 2));   }   private static float[] toHSB(Color aColor) {     return Color.RGBtoHSB(aColor.getRed(), aColor.getGreen(), aColor.getBlue(), null);   }   private static Map<String, Color> buildNameToColorMap() {     Map<String, Color> colorMap = new HashMap<String, Color>();     for (Field field : Color.class.getDeclaredFields()) {       if (isConstantColorField(field)) {         try {           Color color = (Color)field.get(null);           colorMap.put(field.getName().toUpperCase(), color);         }         catch (IllegalAccessException e) {           // Should not occur because the field is public and static         }       }     }     colorMap.put("DARKGREY", getColor("555555"));     colorMap.put("DARKBLUE", getColor("000055"));     colorMap.put("DARKRED", getColor("550000"));     colorMap.put("DARKGREEN", getColor("005500"));     colorMap.put("DARK_GREY", getColor("555555"));     colorMap.put("DARK_BLUE", getColor("000055"));     colorMap.put("DARK_RED", getColor("550000"));     colorMap.put("DARK_GREEN", getColor("005500"));     return colorMap;   }   private static boolean isConstantColorField(Field field) {     return Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())            && Color.class == field.getType();   }   private static String toHexString(Color color) {     return Integer.toHexString(color.getRGB()).substring(2);   } }