Christopher Perry
Christopher Perry

Reputation: 39225

How to parse hex color String to Integer

I'm working on some code in Robolectric, namely IntegerResourceLoader. The following method is throwing a RuntimeException when rawValue is something such as 0xFFFF0000:

@Override
public Object convertRawValue( String rawValue ) {
    try {
        return Integer.parseInt( rawValue );
    } catch ( NumberFormatException nfe ) {
        throw new RuntimeException( rawValue + " is not an integer." );
    }
}

I tried using Integer.decode(String) but that throws a NumberFormatException even though the grammar appears to be correct.

Upvotes: 4

Views: 5845

Answers (4)

TpoM6oH
TpoM6oH

Reputation: 8585

This is how android does it:

private int parseColor(String colorString) {
    if (colorString.charAt(0) == '#') {
        // Use a long to avoid rollovers on #ffXXXXXX
        long color = Long.parseLong(colorString.substring(1), 16);
        if (colorString.length() == 7) {
            // Set the alpha value
            color |= 0x00000000ff000000;
        } else if (colorString.length() != 9) {
            throw new IllegalArgumentException("Unknown color");
        }
        return (int)color;
    }
    throw new IllegalArgumentException("Unknown color");
}

Upvotes: 2

Alex Gitelman
Alex Gitelman

Reputation: 24722

decode() is the right method to call but it fails because 0xFFFF0000 is higher than 0x7fffffff max limit for integer. You may want to consider Long.

Upvotes: 6

Elliott Hill
Elliott Hill

Reputation: 961

If you can strip off the 0x from the front then you can set the radix of parseInt(). So Integer.parseInt(myHexValue,16)

See http://docs.oracle.com/javase/6/docs/api/java/lang/Integer.html#parseInt(java.lang.String, int) for more information

Upvotes: 1

Brian
Brian

Reputation: 17309

The following method is throwing a RuntimeException when rawValue is something such as 0xFFFF0000

This is because Integer.parseInt isn't designed to handle the 0x prefix.

I tried using Integer.decode(String) but that throws a NumberFormatException even though the grammar appears to be correct.

From Integer.decode Javadoc (linked in your question):

This sequence of characters must represent a positive value or a NumberFormatException will be thrown.

0xFFFF0000 is a negative number, and so this is likely what's causing the exception to be thrown here.

Solution:

If you know that the value given will be in the form 0x[hexdigits], then you can use Integer.parseInt(String, int) which takes the radix. For hexadecimal, the radix is 16. Like so:

return Integer.parseInt(rawValue.split("[x|X]")[1], 16);

This uses the regex [x|X] to split the string, which will separate rawValue on either the lower-case or upper-case "x" character, then passes it to parseInt with a radix of 16 to parse it in hexadecimal.

Upvotes: 2

Related Questions