org.apache.wicket.markup.html.image.resource.RenderedDynamicImageResource.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.wicket.markup.html.image.resource.RenderedDynamicImageResource.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket.markup.html.image.resource;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.lang.ref.SoftReference;

import org.apache.wicket.request.resource.DynamicImageResource;
import org.apache.wicket.util.time.Time;

/**
 * A DynamicImageResource subclass that allows easy rendering of regeneratable (unbuffered) dynamic
 * images. A RenderedDynamicImageResource implements the abstract method render(Graphics2D) to
 * create/re-create a given image on-the-fly. When a RenderedDynamicImageResource is serialized, the
 * image state is transient, which means it will disappear when the resource is sent over the wire
 * and then will be recreated when required.
 * <p>
 * The format of the image (and therefore the resource's extension) can be specified with
 * setFormat(String). The default format is "PNG" because JPEG is lossy and makes generated images
 * look bad and GIF has patent issues.
 * 
 * @see org.apache.wicket.markup.html.image.resource.DefaultButtonImageResource
 * @see org.apache.wicket.markup.html.image.resource.DefaultButtonImageResourceFactory
 * @author Jonathan Locke
 * @author Gili Tzabari
 * @author Johan Compagner
 */
public abstract class RenderedDynamicImageResource extends DynamicImageResource {
    private static final long serialVersionUID = 1L;

    /** Height of image */
    private int height = 100;

    /** Transient image data so that image only needs to be generated once per VM */
    private transient SoftReference<byte[]> imageData;

    /** Type of image (one of BufferedImage.TYPE_*) */
    private int type = BufferedImage.TYPE_INT_RGB;

    /** Width of image */
    private int width = 100;

    /**
     * Constructor.
     * 
     * @param width
     *            Width of image
     * @param height
     *            Height of image
     */
    public RenderedDynamicImageResource(final int width, final int height) {
        this.width = width;
        this.height = height;
    }

    /**
     * Constructor.
     * 
     * @param width
     *            Width of image
     * @param height
     *            Height of image
     * @param format
     *            The format of the image (jpg, png or gif)
     */
    public RenderedDynamicImageResource(final int width, final int height, String format) {
        super(format);
        this.width = width;
        this.height = height;
    }

    /**
     * @return Returns the height.
     */
    public synchronized int getHeight() {
        return height;
    }

    /**
     * @return Returns the type (one of BufferedImage.TYPE_*).
     */
    public synchronized int getType() {
        return type;
    }

    /**
     * @return Returns the width.
     */
    public synchronized int getWidth() {
        return width;
    }

    /**
     * Causes the image to be redrawn the next time its requested.
     */
    public synchronized void invalidate() {
        imageData = null;
    }

    /**
     * @param height
     *            The height to set.
     */
    public synchronized void setHeight(int height) {
        this.height = height;
        invalidate();
    }

    /**
     * @param type
     *            The type to set (one of BufferedImage.TYPE_*).
     */
    public synchronized void setType(int type) {
        this.type = type;
        invalidate();
    }

    /**
     * @param width
     *            The width to set.
     */
    public synchronized void setWidth(int width) {
        this.width = width;
        invalidate();
    }

    @Override
    protected byte[] getImageData(Attributes attributes) {
        // get image data is always called in sync block
        byte[] data = null;
        if (imageData != null) {
            data = imageData.get();
        }
        if (data == null) {
            data = render(attributes);
            imageData = new SoftReference<byte[]>(data);
            setLastModifiedTime(Time.now());
        }
        return data;
    }

    /**
     * Renders this image
     * 
     * @param attributes
     *            the current request attributes
     * @return The image data
     */
    protected byte[] render(final Attributes attributes) {
        while (true) {
            final BufferedImage image = new BufferedImage(getWidth(), getHeight(), getType());
            if (render((Graphics2D) image.getGraphics(), attributes)) {
                return toImageData(image);
            }
        }
    }

    /**
     * Override this method to provide your rendering code.
     * 
     * @param graphics
     *            The graphics context to render on.
     * @param attributes
     *            the current request attributes
     * @return {@code true} if the image was rendered. {@code false} if the image size was changed
     *         by the rendering implementation and the image should be re-rendered at the new size.
     */
    protected abstract boolean render(Graphics2D graphics, final Attributes attributes);
}