Drag and Drop Effects, Part 1 (Swing Demo)

You can run the WebStart demo or, as usual, download its source code. If you have installed Mustang I really encourage you to launch the OpenGL accelerated version of the demo.

Disclaimer: This demo was tested on Windows XP (Pentium M 1.8 Ghz) with J2SE 1.5 and Java SE 1.6, and on MacOS X (PowerBook 1.33 Ghz) with J2SE 1.5. I encountered many performances issues when writing this demo and they are all solved on my two test machines. Nevertheless, you might run into the same problems, so don't be surprised. Also drag and drop in the demo still suffers from bugs when used in “extreme” ways. So, I know :)

I admit, I like drag and drop effects. Photo Collage demo is inspired by photo management software such as Apple's iPhoto, Google's Picasa or even Microsoft's Max. The demo you can try today is only the first part of the final demo which will rock big time, trust me. Here is what the application looks like:

Photo Collage

Choose a picture from the list on the left and drag it over the window to the image viewer on the right:

Photo Collage

Then drop the picture on the image viewer to see an animated transition. You'll see the thumbnail grows and fade out while the full picture will fade in:

Photo Collage
Photo Collage

Finally, in case you don't like my photographs, you can add your own pictures in the list on the left. Simply drag and drop a picture from your hard drive to the list:

Photo Collage

While implementing the last bits of the application, I ran into a very interesting problem that Chris Campbell and Chet Haase helped me to fix, and I cannot thank them enough for that. First of all, the demo performs much better on Java SE 1.6 than on J2SE 1.5. Also, activating the OpenGL pipeline provides even better performances with Java SE 1.6 whereas on J2SE 1.5 it sucks. The first problem I had was related to the drawing of the thumbnails in the list. Each “note” is drawn using a PNG file and this happened to be really slow both on Java 1.5 and 1.6. I fixed this issue using VolatileImage. This solved performances issues when scrolling the list but not when dragging the thumbnails.

private void renderOffscreen(boolean create) {
    do {
        if (create ||
            buffer.validate(getGraphicsConfiguration()) ==
                VolatileImage.IMAGE_INCOMPATIBLE) {
            buffer = createVolatileImage(getItemView().getWidth(),

        Graphics2D g2 = buffer.createGraphics();

        g2.drawImage(getItemView(), 0, 0,  null);

        g2.drawImage(image, 26, 21, 127, (int) (127 / ratio), null);
        g2.drawRect(25, 20, 128, (int) (127 / ratio) + 1);
        FontMetrics metrics = g2.getFontMetrics();
        g2.drawString(name, 26.0f, 130.0f + metrics.getAscent());
    } while (buffer.contentsLost());

protected void paintComponent(Graphics g) {
    if (isVisible()) {
        do {
            if (buffer == null) {
            } else {
                int returnCode = buffer.validate(getGraphicsConfiguration());
                if (returnCode == VolatileImage.IMAGE_RESTORED) {
                } else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
            g.drawImage(buffer, 0, 0, this);
     } while (buffer.contentsLost());

Wherever thumbnails are drawn on the screen, I call Graphics.drawImage(image, x, y, width, height, observer) to scale the image down. Oddly enough, J2SE 1.5 was really slow to perform this operation. Chris finally figured out this was because the pictures were not in a format compatible with the screen. Converting the pictures into compatible images solved all the performances issues:

package org.progx.collage.ui;

import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;

public class Java2dHelper {
  public static BufferedImage loadCompatibleImage(URL resource) throws IOException {
    BufferedImage image = ImageIO.read(resource);
    GraphicsConfiguration configuration = GraphicsEnvironment.
    BufferedImage compatibleImage = configuration.createCompatibleImage(image.getWidth(),
    Graphics g = compatibleImage.getGraphics();
    g.drawImage(image, 0, 0, null);
    return compatibleImage;

That's right, this solves all the performances issues! Using this new knowledge, I decided to get rid of the VolatileImage used in the list. Performances were really bad again. After profiling the application with NetBeans I discovered that 96% of the drawing time was spent in the call responsible for drawing the picture of the “notes”. Instead of going back to VolatileImage, I tried to convert the picture of the “note” into a compatible image. Performances were better (as fast on 1.5 and 1.6) but not as good as with VolatileImage. This was due to the glass pane I use for the drag and drop: repainting it caused to repaint the entire UI, therefore triggering the slow repainting of the list.

To conclude, if you're doing any drawing with pictures, especially when you scale them, convert them into compatible images.

2 Responses to “Drag and Drop Effects, Part 1 (Swing Demo)”

  1. Jessica says:

    This advice is really going to help, thanks.

  2. Christian Ortiz says:

    We Can I Get Source Code..