Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
/**
 * 
 */
package com.clinigrid.form.ui.tree;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.wicket.Application;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.markup.html.image.resource.RenderedDynamicImageResource;
import org.apache.wicket.util.resource.ResourceStreamNotFoundException;

/**
 * Dynamic image resource
 * 
 * @author Antoine
 * 
 */
public class CompositeImageResource extends RenderedDynamicImageResource
		implements ImageObserver {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * Default icon width. Other implementations could obtain this data from the
	 * images meta datas
	 */
	private static final int ICON_WIDTH = 16;

	/**
	 * Default icon height. Other implementations could obtain this data from
	 * the images meta datas
	 */
	private static final int ICON_HEIGHT = 16;

	/**
	 * {@link ResourceReference} to the base image to decorate
	 */
	private final ResourceReference source;

	/**
	 * {@link ResourceReference}[] to use as decorations (will be stacked over
	 * the source)
	 */
	private final ResourceReference[] overlays;

	/**
	 * Internal field to monitor the awt image rendering process
	 */
	private int ongoing = 0;

	/**
	 * @param width
	 * @param height
	 */
	public CompositeImageResource(ResourceReference originalIcon,
			ResourceReference... overlays) {
		super(ICON_WIDTH, ICON_HEIGHT);
		// Insure transparency management
		setType(BufferedImage.TYPE_INT_ARGB);
		this.source = originalIcon;
		this.source.bind(Application.get());
		this.overlays = overlays;
		for (ResourceReference ref : this.overlays) {
			// Not sure this is the right way to ensure binding?
			ref.bind(Application.get());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.wicket.markup.html.image.resource.RenderedDynamicImageResource#render(java.awt.Graphics2D)
	 */
	@Override
	protected boolean render(Graphics2D g2) {
		BufferedImage baseIcon;
		BufferedImage[] errorIcons = new BufferedImage[overlays.length];
		ongoing = 0;
		// Try reading the original images from the resource reference resource
		// streams
		try {
			baseIcon = ImageIO.read(source.getResource().getResourceStream()
					.getInputStream());
			ongoing++;
			for (int i = 0; i < overlays.length; i++) {
				errorIcons[i] = ImageIO.read(overlays[i].getResource()
						.getResourceStream().getInputStream());
				ongoing++;
			}
		} catch (IOException e) {
			throw new WicketRuntimeException(e);
		} catch (ResourceStreamNotFoundException e) {
			throw new WicketRuntimeException(e);
		}
		// Prepare g2 for trnasparency
		g2.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
		Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, ICON_WIDTH,
				ICON_HEIGHT);
		g2.fill(rect);
		
		// Prepare g2 for image overlay
		g2
				.setComposite(AlphaComposite.getInstance(
						AlphaComposite.SRC_OVER, 1f));
		if (g2.drawImage(baseIcon, null, this)) {
			ongoing--;
		}
		for (Image overlay : errorIcons) {
			g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
					1f));
			if (g2.drawImage(overlay, null, this)) {
				ongoing--;
			}
		}
		// Wait until the awt process finishes loading the images
		while (ongoing > 0) {
			System.err.println("Remaining : " + ongoing);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return true;
	}

	/* (non-Javadoc)
	 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
	 */
	@Override
	public boolean imageUpdate(Image img, int infoflags, int x, int y,
			int width, int height) {
		boolean done = (infoflags & ImageObserver.ALLBITS) != 0;
		if (done) {
			ongoing--;
		}
		return done;
	}
}

...

Code Block
import java.io.Serializable;

import javax.swing.tree.TreeNode;

import org.apache.wicket.Component;
import org.apache.wicket.IResourceListener;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.Resource;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.extensions.markup.html.tree.Tree;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.link.Link;


public class DecoratedTree extends Tree {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8790640156918181807L;

	static final ResourceReference ERROR = new ResourceReference(
			FormTree.class, "error.gif");


	[...]

	@Override
	protected Component newNodeIcon(MarkupContainer parent, String id,
			final TreeNode node) {
		class IconComponent extends WebMarkupContainer implements
				IResourceListener {

			private static final long serialVersionUID = 1L;

			private Resource icon;

			private ResourceReference reference;

			IconComponent(String id) {
				super(id);
				// Obtain the original image resource reference 
				ResourceReference icon = ...
				if (hasError) {
					// Error? Let's use the CompositeImageResource with our icon 
					// and the static ERROR decoration
					this.icon = new CompositeImageResource(icon, ERROR);
				} else {
					// No error? let's stick to the source resource reference
					this.reference = icon;
				}
			}

			protected void onComponentTag(ComponentTag tag) {
				super.onComponentTag(tag);
				// Obtain an url to our image, wheter it be the original icon
				// or the generated image
				CharSequence url = reference != null ? RequestCycle.get()
						.urlFor(reference) : this
						.urlFor(IResourceListener.INTERFACE);

				tag.put("style", "background-image: url('"
						+ RequestCycle.get().getOriginalResponse().encodeURL(
								url) + "')");
			}

			@Override
			public void onResourceRequested() {
				this.icon.onResourceRequested();

			}
		}
		return new IconComponent(id);
	}

	[...]
}