Andres is a DZone Zone Leader and has posted 143 posts at DZone. You can read more from them at their website. View Full User Profile

GraphicsBuilder Tutorial III: Paints & Colors

  • submit to reddit

Third part of the GraphicsBuilder tutorial series, now it is the turn to demonstrate how you can apply colors and paints (flat colors and gradients) to shapes and outlines, even borders, to your Java2D drawings.


In the first and second part of this series I have shown how Graphicsbuilder can help you draw shapes, outlines and apply an arbitrary clip to your Java2D drawings thanks to GraphicsBuilder. Now is the time to pick up speed and review the options GraphicsBuilder lends you to add some color to your drawings.

Flat Colors 

You may have noticed in the previous parts that two properties were used to give color to shapes and outlines, these are borderColor and fill. The first one (as the name implies) defines the color to be applied to the border (or the stroke as we will see in a later chapter), the second one defines the color that will fill the shape's area. The examples have shown that you may specify a color literal, but as a matter of fact you can use any java.awt.Color instance. The literals are a shortcut for the most common colors (java.awt.Color defines 13 basic colors only), but GraphicsBuilder provides additional color literals for the full range of CSS2 color set like 'aqua', 'bisque', 'indigo', steelBlue' among others.

The color node will take care of translating a color literal into the proper java.awt.color representation, relying on the ColorCache singleton. ColorCache is the one responsible for holding a map of color names and their values, you can use it to store new colors if you want to. Color properties that accept a color literal also use the ColorCache under the covers.

Enough theory, let's see some examples of color properties and the color node in action. The following image shows 5 rectangles, each with a black border and different color as fill, notice that thw white one is translucent.


rect( x: 0, y: 0, width: 50, height: 50, borderColor: 'black', fill: 'red' )
rect( x: 50, y: 0, width: 50, height: 50, borderColor: color('black') ){
colorPaint( 'blue' )
rect( x: 0, y: 50, width: 50, height: 50, borderColor: color('#000000'), fill: color('#FF0') )
rect( x: 50, y: 50, width: 50, height: 50, borderColor: color(red:0) ){
colorPaint( green: 1 )
rect( x: 25, y: 25, width: 50, height: 50, borderColor: 'black' ){
colorPaint( color('white').derive(alpha:0.5) )

Let's examine each rectangle one by one. The red rectangle sets its color properties in the same way the previous examples did, nothing new here. The blue rectangle introduces the color node and the colorPaint node, both of them have the same properties, the difference is that colorPaint returns a PaintProvider, an internal class of GraphicsBuilder that deals with paints, whereas color (as you already know) returns a java.awt.Color. The yellow rectangle shows another feature of the color node, it can translate hexadecimal color literals, either in full or compact mode. The green rectangle shows another set of properties for the color node, it accepts a combination of [red,green,blue,alpha] values, ranging from 0f..1f and 1i..255i; unspecified properties will have a zero (0) assigned to their values, that is why the border's black color can be set with color(red:0). The last rectangle, the white translucent one, shows that colorPaint accepts the output of color, and that java.awt.color has been enhanced (through Groovy MetaClasses) with a new method derive, which will let you create a new color from a base one; this method accepts a combination of [red,green,blue,alpha] properties.

Two-color Gradients 

Flat colors are ok but everybody knows that gradients are better, they add depth and warm to any drawing, so let's see what GraphicsBuilder has to offer. Since the early days of Java2D developers had the option to draw gradients using java.awt.GradientPaint, which will let you draw a two-color linear gradient, there is really not much mystery about it, which is why the gradientPaint node is pretty straight forward, as the following example shows


rect( x: 0, y: 0, width: 100, height: 50, borderColor: 'black'  ){
gradientPaint( x1: 0, y1: 0, x2: 100, y2: 50, color2: 'orange' )
rect( x: 100, y: 0, width: 100, height: 50, borderColor: 'black' ){
gradientPaint( x1: 0, y1: 0, x2: 50, y2: 30, color2: 'orange' )
rect( x: 0, y: 50, width: 100, height: 50, borderColor: 'black' ){
gradientPaint( x1: 0, y1: 0, x2: 50, y2:30, color2: 'orange', stretch: yes )
rect( x: 100, y: 50, width: 100, height: 50, borderColor: 'black' ){
gradientPaint( x1: 0, y1: 0, x2: 50, y2: 30, color2: 'orange', fit: no )

GradientPaint requires a line and two colors, it has some sensible defaults (like color1 being 'black'). you will notice that the top rectangles have the same paint even though the line definition for each one is different, this is because gradientPaint will try to fit the gradient in the shape's bounds by default, retaining the aspect ratio. The left bottom rectangle shows another property, stretch, that will also try to fit the gradient in the shape's bounds, but it doesn't retain the aspect ratio. The last rectangle shows how the gradient is drawn when fit is disabled. It is worth noting that stretch and fit are mutually exclusive, if you enable one the other will be disabled automatically.

Published at DZone with permission of its author, Andres Almiray.