Fork us on GitHub

In the Shadow

Dropshadow effect is now easier and more appealing
Post Image

In the Shadow

Diamond asked us about an easy way to do dropshadows in Codename One to which I answered that it’s pretty easy thanks to our Gaussian blur support…​

We ended up with this code which is usable but probably not as intuitive for most:

Form hi = new Form("Drop Shadow", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER));

FontImage mm = FontImage.createMaterial(FontImage.MATERIAL_PERSON, "Button", 30);
int[] rgb = mm.toImage().getRGB();
for(int iter = 0 ; iter < rgb.length ; iter++) {
    rgb[iter] = rgb[iter] & 0xff000000;
}
Image shadow = Image.createImage(rgb, mm.getWidth(), mm.getHeight());
if(Display.getInstance().isGaussianBlurSupported()) {
    shadow = Display.getInstance().gaussianBlurImage(shadow, 10);
}

Label top = new Label(mm, "Container");
Label bottom = new Label(shadow, "Container");
bottom.getAllStyles().setMargin(1, 0, 1, 0);
bottom.getAllStyles().setMarginUnit(Style.UNIT_TYPE_DIPS);
hi.add(BorderLayout.CENTER, LayeredLayout.encloseIn(bottom, top));

hi.show();

The effect is attractive and commonplace so I think it would be great to add it universally so we added two methods which will be a part of the coming update. These methods are in the Effects class and are both simple utility methods. Once creates a shadow and incorporates it into a new image at the given location. The other returns the shadow alone which you can shift/position as you see fit (e.g. if you have similarly shaped images this might also be useful in terms of CPU/RAM).

/**
 * Generates a shadow for the source image and returns a new larger image containing the shadow
 *
 * @param source the source image for whom the shadow should be generated
 * @param blurRadius a shadow is blurred using a gaussian blur when available, a value of 10 is often satisfactory
 * @param opacity the opacity of the shadow between 0 - 1 where 1 is completely opaque
 * @param xDistance the distance on the x axis from the main image body in pixels e.g. a negative value will represent a lightsource from the right (shadow on the left)
 * @param yDistance the distance on the y axis from the main image body in pixels e.g. a negative value will represent a lightsource from the bottom (shadow on top)
 * @return a new image whose size incorporates x/yDistance
 */
public static Image dropshadow(Image source, int blurRadius, float opacity, int xDistance, int yDistance);

/**
 * Generates a shadow for the source image and returns either the shadow itself or the image merged with the
 * shadow.
 *
 * @param source the source image for whom the shadow should be generated
 * @param blurRadius a shadow is blurred using a gaussian blur when available, a value of 10 is often satisfactory
 * @param opacity the opacity of the shadow between 0 - 1 where 1 is completely opaque
 * @return an image containing the shadow for source
 */
public static Image dropshadow(Image source, int blurRadius, float opacity);

This can result in simple code to do a drop shadow effect:

Form hi = new Form("Drop Shadow", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER));

int twoMM = Display.getInstance().convertToPixels(2);
Image img = duke.scaledWidth(Display.getInstance().getDisplayWidth() / 2);
hi.add(BorderLayout.CENTER, new Label(Effects.dropshadow(img, 10, 0.8f, twoMM, twoMM), "Container"));

hi.show();
The variable duke is the image of the icon placed into the src directory
Share this Post:

Posted by Shai Almog

Shai is the co-founder of Codename One. He's been a professional programmer for over 25 years. During that time he has worked with dozens of companies including Sun Microsystems.
For more follow Shai on Twitter & github.