import java.util.Map;
import java.util.Random;
+/**
+ * A class with utility methods for manipulating AWT colours/colors
+ */
public class ColorUtils
{
private static final int MAX_CACHE_SIZE = 1729;
+
/*
* a cache for colours generated from text strings
*/
* 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>
+ * <li>a six digit rgb hex colour value (without prefix) e.g. ff0000</li>
+ * <li>a comma-separated rgb triple e.g. 100,50,150</li>
* </ul>
*
* @param colour
colour = colour.trim();
Color col = null;
- try
- {
- int value = Integer.parseInt(colour, 16);
- col = new Color(value);
- } catch (NumberFormatException ex)
+ if (colour.length() == 6 && StringUtils.isHexString(colour))
{
- col = Platform.getColorFromName(colour);
+ try
+ {
+ int value = Integer.parseInt(colour, 16);
+ col = new Color(value);
+ } catch (NumberFormatException ex)
+ {
+ }
}
if (col == null)
{
- col = ColorUtils.getAWTColorFromName(colour);
+ col = ColorUtils.getColorFromName(colour);
}
if (col == null)
int b = Integer.parseInt(tokens[2].trim());
col = new Color(r, g, b);
}
- } catch (Exception ex)
+ } catch (IllegalArgumentException ex)
{
// non-numeric token or out of 0-255 range
}
/**
* Returns the Color constant for a given colour name e.g. "pink", or null if
- * the name is not recognised
+ * the name is not recognised. Currently recognises only AWT colour names, but
+ * could be extended to support others e.g. standard html colour names.
*
* @param name
* @return
*/
- public static Color getAWTColorFromName(String name)
+ public static Color getColorFromName(String name)
{
- return Platform.getColorFromName(name); // BH 2019 -- allows for wide range
- // of JavaScript colors (for
- // JavaScript only)
+ if (name == null)
+ {
+ return null;
+ }
+ // or make a static map; or use reflection on the field name
+ switch (name.toLowerCase())
+ {
+ case "black":
+ return Color.black;
+ case "blue":
+ return Color.blue;
+ case "cyan":
+ return Color.cyan;
+ case "darkgray":
+ return Color.darkGray;
+ case "gray":
+ return Color.gray;
+ case "green":
+ return Color.green;
+ case "lightgray":
+ return Color.lightGray;
+ case "magenta":
+ return Color.magenta;
+ case "orange":
+ return Color.orange;
+ case "pink":
+ return Color.pink;
+ case "red":
+ return Color.red;
+ case "white":
+ return Color.white;
+ case "yellow":
+ return Color.yellow;
+ default:
+ return null;
+ }
}
}
}
/**
- * @param c
- */
- public static Color getColorFromName(String name)
- {
- if (name == null)
- {
- return null;
- }
- /**
- * @j2sNative
- *
- * return swingjs.JSUtil.getColorFromName$S(name);
- */
- {
- // or make a static map; or use reflection on the field name
- switch (name.toLowerCase())
- {
- case "black":
- return Color.black;
- case "blue":
- return Color.blue;
- case "cyan":
- return Color.cyan;
- case "darkgray":
- return Color.darkGray;
- case "gray":
- return Color.gray;
- case "green":
- return Color.green;
- case "lightgray":
- return Color.lightGray;
- case "magenta":
- return Color.magenta;
- case "orange":
- return Color.orange;
- case "pink":
- return Color.pink;
- case "red":
- return Color.red;
- case "white":
- return Color.white;
- case "yellow":
- return Color.yellow;
- default:
- return null;
- }
-
- }
- }
-
- /**
* Initialize Java debug logging. A representative sample -- adapt as desired.
*/
public static void startJavaLogging()
{
return null;
}
- List<String> jv = new ArrayList<String>();
+ List<String> jv = new ArrayList<>();
int cp = 0, pos, escape;
boolean wasescaped = false, wasquoted = false;
String lstitem = null;
}
return text;
}
+
+ /**
+ * Answers true if the string is not empty and consists only of digits, or
+ * characters 'a'-'f' or 'A'-'F', else false
+ *
+ * @param s
+ * @return
+ */
+ public static boolean isHexString(String s)
+ {
+ int j = s.length();
+ if (j == 0)
+ {
+ return false;
+ }
+ for (int i = 0; i < j; i++)
+ {
+ int c = s.charAt(i);
+ if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f')
+ && !(c >= 'A' && c <= 'F'))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
}
assertNull(ColorUtils.brighterThan(null));
}
- /**
- * @see http://www.rtapo.com/notes/named_colors.html
- */
@Test(groups = { "Functional" })
public void testToTkCode()
{
// 'hex' prefixes _not_ wanted here
assertNull(ColorUtils.parseColourString("0x" + hexColour));
assertNull(ColorUtils.parseColourString("#" + hexColour));
- // out of range, but Color constructor just or's the rgb value with 0
- assertEquals(Color.black, ColorUtils.parseColourString("1000000"));
+ // hex values must be 6 hex digits
+ assertNull(ColorUtils.parseColourString("1000000"));
+ assertNull(ColorUtils.parseColourString("0ff00"));
/*
* by RGB triplet
*/
assertNull(ColorUtils.parseColourString(null));
assertNull(ColorUtils.parseColourString("rubbish"));
- assertEquals(Color.WHITE, ColorUtils.parseColourString("-1"));
+ assertNull(ColorUtils.parseColourString("-1"));
assertNull(ColorUtils.parseColourString(String
.valueOf(Integer.MAX_VALUE)));
assertNull(ColorUtils.parseColourString("100,200,300")); // out of range
@Test(groups = "Functional")
public void testGetAWTColorFromName() {
- assertEquals(Color.white, ColorUtils.getAWTColorFromName("white"));
- assertEquals(Color.white, ColorUtils.getAWTColorFromName("White"));
- assertEquals(Color.white, ColorUtils.getAWTColorFromName("WHITE"));
- assertEquals(Color.pink, ColorUtils.getAWTColorFromName("pink"));
- assertNull(ColorUtils.getAWTColorFromName("mauve")); // no such name
- assertNull(ColorUtils.getAWTColorFromName(""));
- assertNull(ColorUtils.getAWTColorFromName(null));
+ assertEquals(Color.white, ColorUtils.getColorFromName("white"));
+ assertEquals(Color.white, ColorUtils.getColorFromName("White"));
+ assertEquals(Color.white, ColorUtils.getColorFromName("WHITE"));
+ assertEquals(Color.pink, ColorUtils.getColorFromName("pink"));
+ assertNull(ColorUtils.getColorFromName("mauve")); // no such name
+ assertNull(ColorUtils.getColorFromName(""));
+ assertNull(ColorUtils.getColorFromName(null));
}
@Test(groups = "Functional")
package jalview.util;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
import jalview.gui.JvOptionPane;
public void testListToDelimitedString()
{
assertEquals("", StringUtils.listToDelimitedString(null, ";"));
- List<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<>();
assertEquals("", StringUtils.listToDelimitedString(list, ";"));
list.add("now");
assertEquals("now", StringUtils.listToDelimitedString(list, ";"));
assertEquals("kdHydro < 12.53",
StringUtils.stripHtmlTags("kdHydro < 12.53"));
}
+
+ @Test(groups = { "Functional" })
+ public void testIsHexString()
+ {
+ assertFalse(StringUtils.isHexString(""));
+ assertTrue(StringUtils.isHexString("0123456789abcdefABCDEF"));
+ assertFalse(StringUtils.isHexString("g"));
+ try
+ {
+ StringUtils.isHexString(null);
+ fail("expected exception");
+ } catch (NullPointerException e)
+ {
+ // expected
+ }
+ }
}