package jalview.util;
import java.awt.Color;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Random;
public class ColorUtils
{
+ private static final int MAX_CACHE_SIZE = 1729;
+ /*
+ * a cache for colours generated from text strings
+ */
+ static Map<String, Color> myColours = new HashMap<>();
/**
* Generates a random color, will mix with input color. Code taken from
* prop = proportion of the way value is from minValue to maxValue
*/
float prop = (value - minValue) / (maxValue - minValue);
- float r = minColour.getRed() + prop
- * (maxColour.getRed() - minColour.getRed());
- float g = minColour.getGreen() + prop
- * (maxColour.getGreen() - minColour.getGreen());
- float b = minColour.getBlue() + prop
- * (maxColour.getBlue() - minColour.getBlue());
+ float r = minColour.getRed()
+ + prop * (maxColour.getRed() - minColour.getRed());
+ float g = minColour.getGreen()
+ + prop * (maxColour.getGreen() - minColour.getGreen());
+ float b = minColour.getBlue()
+ + prop * (maxColour.getBlue() - minColour.getBlue());
return new Color(r / 255, g / 255, b / 255);
}
return new Color(red, green, blue);
}
}
+
+ /**
+ * Parses a string into a Color, where the accepted formats are
+ * <ul>
+ * <li>an AWT colour name e.g. white</li>
+ * <li>a hex colour value (without prefix) e.g. ff0000</li>
+ * <li>an rgb triple e.g. 100,50,150</li>
+ * </ul>
+ *
+ * @param colour
+ * @return the parsed colour, or null if parsing fails
+ */
+ public static Color parseColourString(String colour)
+ {
+ if (colour == null)
+ {
+ return null;
+ }
+ colour = colour.trim();
+
+ Color col = null;
+ try
+ {
+ int value = Integer.parseInt(colour, 16);
+ col = new Color(value);
+ } catch (NumberFormatException ex)
+ {
+ }
+
+ if (col == null)
+ {
+ col = ColorUtils.getAWTColorFromName(colour);
+ }
+
+ if (col == null)
+ {
+ try
+ {
+ String[] tokens = colour.split(",");
+ if (tokens.length == 3)
+ {
+ int r = Integer.parseInt(tokens[0].trim());
+ int g = Integer.parseInt(tokens[1].trim());
+ int b = Integer.parseInt(tokens[2].trim());
+ col = new Color(r, g, b);
+ }
+ } catch (Exception ex)
+ {
+ // non-numeric token or out of 0-255 range
+ }
+ }
+
+ return col;
+ }
+
+ /**
+ * Constructs a colour from a text string. The hashcode of the whole string is
+ * scaled to the range 0-135. This is added to RGB values made from the
+ * hashcode of each third of the string, and scaled to the range 20-229.
+ *
+ * @param name
+ * @return
+ */
+ public static Color createColourFromName(String name)
+ {
+ if (name == null)
+ {
+ return Color.white;
+ }
+ if (myColours.containsKey(name))
+ {
+ return myColours.get(name);
+ }
+ int lsize = name.length();
+ int start = 0;
+ int end = lsize / 3;
+
+ int rgbOffset = Math.abs(name.hashCode() % 10) * 15; // 0-135
+
+ /*
+ * red: first third
+ */
+ int r = Math.abs(name.substring(start, end).hashCode() + rgbOffset)
+ % 210 + 20;
+ start = end;
+ end += lsize / 3;
+ if (end > lsize)
+ {
+ end = lsize;
+ }
+
+ /*
+ * green: second third
+ */
+ int g = Math.abs(name.substring(start, end).hashCode() + rgbOffset)
+ % 210 + 20;
+
+ /*
+ * blue: third third
+ */
+ int b = Math.abs(name.substring(end).hashCode() + rgbOffset) % 210 + 20;
+
+ Color color = new Color(r, g, b);
+
+ if (myColours.size() < MAX_CACHE_SIZE)
+ {
+ myColours.put(name, color);
+ }
+
+ return color;
+ }
+
+ /**
+ * Returns the Color constant for a given colour name e.g. "pink", or null if
+ * the name is not recognised
+ *
+ * @param name
+ * @return
+ */
+ public static Color getAWTColorFromName(String name)
+ {
+ if (name == null)
+ {
+ return null;
+ }
+ Color col = null;
+ name = name.toLowerCase();
+
+ // or make a static map; or use reflection on the field name
+ switch (name)
+ {
+ case "black":
+ col = Color.black;
+ break;
+ case "blue":
+ col = Color.blue;
+ break;
+ case "cyan":
+ col = Color.cyan;
+ break;
+ case "darkgray":
+ col = Color.darkGray;
+ break;
+ case "gray":
+ col = Color.gray;
+ break;
+ case "green":
+ col = Color.green;
+ break;
+ case "lightgray":
+ col = Color.lightGray;
+ break;
+ case "magenta":
+ col = Color.magenta;
+ break;
+ case "orange":
+ col = Color.orange;
+ break;
+ case "pink":
+ col = Color.pink;
+ break;
+ case "red":
+ col = Color.red;
+ break;
+ case "white":
+ col = Color.white;
+ break;
+ case "yellow":
+ col = Color.yellow;
+ break;
+ }
+
+ return col;
+ }
}