From: gmungoc Date: Mon, 12 Dec 2016 12:28:32 +0000 (+0000) Subject: JAL-2362 return correct lower-case colour; Javadoc; unit test X-Git-Tag: Release_2_10_3b1~357^2~64 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=1f690971e7ffd3c33453e9e6e97653cb3b481169;p=jalview.git JAL-2362 return correct lower-case colour; Javadoc; unit test --- diff --git a/src/jalview/schemes/UserColourScheme.java b/src/jalview/schemes/UserColourScheme.java index 9ae14ca..4bb54f9 100755 --- a/src/jalview/schemes/UserColourScheme.java +++ b/src/jalview/schemes/UserColourScheme.java @@ -99,6 +99,17 @@ public class UserColourScheme extends ResidueColourScheme return schemeName; } + /** + * Parses a string into a Color, where the accepted formats are + * + * + * @param colour + * @return the parsed colour, or null if parsing fails + */ public static Color getColourFromString(String colour) { if (colour == null) @@ -125,19 +136,21 @@ public class UserColourScheme extends ResidueColourScheme { try { - java.util.StringTokenizer st = new java.util.StringTokenizer( - colour, ","); - int r = Integer.parseInt(st.nextToken()); - int g = Integer.parseInt(st.nextToken()); - int b = Integer.parseInt(st.nextToken()); - col = new Color(r, g, b); + 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; - } public static Color createColourFromName(String name) @@ -166,6 +179,21 @@ public class UserColourScheme extends ResidueColourScheme return color; } + /** + * Parse and save residue colours specified as (for example) + * + *
+   *     D,E=red; K,R,H=0022FF; c=100,50,75
+   * 
+ * + * This should be a semi-colon separated list of colours, which may be defined + * by colour name, hex value or comma-separated RGB triple. Each colour is + * defined for a comma-separated list of amino acid single letter codes. (Note + * that this also allows a colour scheme to be defined for ACGT, but not for + * U.) + * + * @param paramValue + */ public void parseAppletParameter(String paramValue) { // TODO: need a function to generate appletParameter colour string from a @@ -184,16 +212,15 @@ public class UserColourScheme extends ResidueColourScheme st2 = new StringTokenizer(residues, " ,"); while (st2.hasMoreTokens()) { - token = st2.nextToken(); + String residue = st2.nextToken(); - if (ResidueProperties.aaIndex[token.charAt(0)] == -1) + int colIndex = ResidueProperties.aaIndex[residue.charAt(0)]; + if (colIndex == -1) { continue; } - int colIndex = ResidueProperties.aaIndex[token.charAt(0)]; - - if (token.equalsIgnoreCase("lowerCase")) + if (residue.equalsIgnoreCase("lowerCase")) { if (lowerCaseColours == null) { @@ -210,7 +237,7 @@ public class UserColourScheme extends ResidueColourScheme continue; } - if (token.equals(token.toLowerCase())) + if (residue.equals(residue.toLowerCase())) { if (lowerCaseColours == null) { @@ -267,4 +294,23 @@ public class UserColourScheme extends ResidueColourScheme lowerCaseColours = lcolours; } + /** + * Returns the colour for the given residue character. If the residue is + * lower-case, and there is a specific colour defined for lower case, that + * colour is returned, else the colour for the upper case residue. + */ + @Override + public Color findColour(char c) + { + if ('a' <= c && c <= 'z' && lowerCaseColours != null) + { + Color colour = lowerCaseColours[symbolIndex[c]]; + if (colour != null) + { + return colour; + } + } + return super.findColour(c); + } + } diff --git a/test/jalview/schemes/UserColourSchemeTest.java b/test/jalview/schemes/UserColourSchemeTest.java index 645d5b8..f4875ee 100644 --- a/test/jalview/schemes/UserColourSchemeTest.java +++ b/test/jalview/schemes/UserColourSchemeTest.java @@ -57,17 +57,24 @@ public class UserColourSchemeTest * by RGB hex code */ String hexColour = Integer.toHexString(Color.RED.getRGB() & 0xffffff); + assertEquals("ff0000", hexColour); assertEquals(Color.RED, UserColourScheme.getColourFromString(hexColour)); // 'hex' prefixes _not_ wanted here assertNull(UserColourScheme.getColourFromString("0x" + hexColour)); assertNull(UserColourScheme.getColourFromString("#" + hexColour)); + // out of range, but Color constructor just or's the rgb value with 0 + assertEquals(Color.black, + UserColourScheme.getColourFromString("1000000")); /* * by RGB triplet */ - String rgb = String.format("%d,%d,%d", Color.red.getRed(), - Color.red.getGreen(), Color.red.getBlue()); - assertEquals(Color.RED, UserColourScheme.getColourFromString(rgb)); + Color c = Color.pink; + String rgb = String.format("%d,%d,%d", c.getRed(), c.getGreen(), + c.getBlue()); + assertEquals("255,175,175", rgb); + assertEquals(c, UserColourScheme.getColourFromString(rgb)); + assertEquals(c, UserColourScheme.getColourFromString("255, 175 , 175")); /* * odds and ends @@ -77,5 +84,40 @@ public class UserColourSchemeTest assertEquals(Color.WHITE, UserColourScheme.getColourFromString("-1")); assertNull(UserColourScheme.getColourFromString(String .valueOf(Integer.MAX_VALUE))); + assertNull(UserColourScheme.getColourFromString("100,200,300")); + assertNull(UserColourScheme.getColourFromString("100,200")); + assertNull(UserColourScheme.getColourFromString("100,200,100,200")); + } + + @Test(groups = "Functional") + public void testParseAppletParameter() + { + UserColourScheme cs = new UserColourScheme("white"); + cs.parseAppletParameter("D,E=red; K,R,H=0022FF; c=10 , 20,30"); + assertEquals(Color.RED, cs.findColour('D')); + assertEquals(Color.RED, cs.findColour('d')); + assertEquals(Color.RED, cs.findColour('E')); + assertEquals(Color.RED, cs.findColour('e')); + Color c1 = new Color(0x0022ff); + assertEquals(c1, cs.findColour('K')); + assertEquals(c1, cs.findColour('R')); + assertEquals(c1, cs.findColour('h')); + Color c2 = new Color(10, 20, 30); + assertEquals(c2, cs.findColour('c')); + + cs = new UserColourScheme("white"); + cs.parseAppletParameter("D,E=red; K,R,H=0022FF; c=10 , 20,30;lowercase=blue;s=pink"); + assertEquals(Color.RED, cs.findColour('D')); + assertEquals(Color.blue, cs.findColour('d')); + assertEquals(Color.RED, cs.findColour('E')); + assertEquals(Color.blue, cs.findColour('e')); + assertEquals(c1, cs.findColour('K')); + assertEquals(c1, cs.findColour('R')); + assertEquals(Color.blue, cs.findColour('h')); + assertEquals(c2, cs.findColour('c')); + // 'lowercase' sets all lower-case not already set to the given colour + assertEquals(Color.blue, cs.findColour('k')); + assertEquals(Color.blue, cs.findColour('a')); + assertEquals(Color.pink, cs.findColour('s')); } }