HSL Color
Posted by Rob Camick on July 5, 2009
The Color class in Java uses Red, Green and Blue (RGB) values to specify a Color. I don’t know about you, but I have no idea how to manipulate a given Color to return a related Color. For example, how would you go about returning a darker or lighter Color? Sure the Color API supports brighter() and darker() methods, but they don’t seem to work that well and you can’t control the degree of brightness or darkness. The API also supports a HSB (Hue, Saturation, Brightness) color space which seemed promising, but didn’t quite return the results I was looking for.
So, I searched the web and found out about the HSL (Hue, Saturation, Luminance) color space. As you can guess from its name you still need to specify 3 values to completely define a unique color:
- hue – represents the color (think colors of the rainbow). Its value is specified in degrees from 0 – 360. Red is 0, green is 120 and blue is 240.
- saturation – represents the purity of the color. Its value is specified as a percentage. 100 percent is fully saturated and 0 percent is gray.
- luminance – represents the brighness of the color. Its value is specified as a percent. 100 percent is white and 0 percent is black.
Each value has its own meaning and therefore you generally only need to change a single value to create a new color that is somehow related to the old color. This is far easier for me to understand then trying to guess how to manipulate RGB values to create a new color.
However, knowing the HSL values doesn’t do us much good because Java only knows how to work with RGB Color objects. So I created the HSLColor class to support conversions between the two color spaces. It also provides methods that enable easy manipulation of the HSL values while returning a Color object that can be used by Java Components. The easiest way to create a HSLColor object is to provide it with a Color object. Although if you know the HSL values you want to use you can create an HSLColor object directly. Once this is done you can manipulate the HSL values using any of the following methods:
- adjustHue – specify the degree of a color
- adjustLuminance – specify an absolute percentage of luminance
- adjustSaturation – specify an absolute percentage of saturation
- adjustShade – adjusting the shade will give you a darker color. You control how much darker the color should be by specifying the adjustmnt percent.
- adjustTone – adjusting the tone will give you a lighter color. You control how much lighter the color should be by specifying the adjustment percent.
- getComplimentary – a complementary color differs from its base color by 180 degrees.
The HSLColor class might come in handy when you want to use a color theme for your component. Maybe you want to have a light background and dark foreground (or vice versa). So instead of just using white and black you can use a different shade and tone of a specific color. Something like:
HSLColor base = new HSLColor( Color.RED );
component.setBackground( base.adjustTone(30) );
component.setForeground( base.adjustShade(30) );
Now, whatever base color you choose the background will be 30% lighter and the foreground 30% darker. The following image gives an example of how the tone changes for various percentages.
Check out the Webstart demo so you can click on the other tabs to get an idea of how the colors change as the different HSL values are adjusted. Hopefully this will make it easier for you to decide on a color theme. You may be able to choose a theme simply by specifying a base color and then use the HSLColor class to adjust the HSL values for other related colors.
Try The Demo
– Using Java™ Web Start (JRE 6 required)

Tim said
Brilliant! Just what I was looking for!
Rob Camick said
Glad it brightened up your day :)
Corey said
This is just great! Thanks for sharing! I have been working at trying to do the same thing through guesswork using RGB and it was such a pain. HSL was the way to go for sure!
Rob Camick said
Hopefully you won’t be seeing red anymore now that you can use HSL instead of RGB.