THIS IS A TEST INSTANCE. ALL YOUR CHANGES WILL BE LOST!!!!
...
Code Block |
---|
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 {
/**
* 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) {
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;
}
}
|
Let's see how to use this for implement a Tree that renders the node's icon decorated with errors, notification, etc... images :
...