Dynamic Image (cache?) problem/bug

asked 2010-12-14 16:26:03 +0800

meh gravatar image meh
57 1


I am trying to upgrade from ZK 5.0.1 to 5.0.5 and encountered a problem with my dynamic images:

I create a set of images within a groupbox. When the user double-clicks on an image, it is moved into a second groupbox and a new set of images appears to choose from. It works fine with 5.0.1, but with 5.0.3 and 5.0.5 the first groupbox (the images to choose from) is not always updated correctly - old images are used rather than the newly created ones.

Any help is greatly appreciated,

Here is the zul file:

<?xml version="1.0" encoding="UTF-8"?>
<zk xmlns="http://www.zkoss.org/2005/zul">
    <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" root="./win"?>
    <window id="win" title="Dynamic Image" border="normal" width="100%" height="100%"
        <vbox hflex="1">
            <label value="Double-click on an icon to choose it."  style="font-size: 18px"/>
            <label value="You will be given new icons to choose from."  style="font-size: 18px"/>
            <label value="See if the new icons have the numbers they should have,"  style="font-size: 18px"/>
            <label value="and if the tooltip matches the number on the icon."  style="font-size: 18px" />

            <separator bar="true" height="15px" />

                <label value="Choices (should be):" style="font-size: 18px" />
                <label id="correctChoices" style="font-size: 24px; color: red" />
            <groupbox id="choicesArea" mold="3d" hflex="1" contentStyle="overflow:auto" ></groupbox>

            <separator bar="true" height="15px" />
            <label value="Picked:" style="font-size: 18px" />
            <groupbox id="pickedArea" mold="3d" hflex="1" droppable="true" height="200px"></groupbox>

And the controller IndexController.java:

package controller;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.DropEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Groupbox;
import org.zkoss.zul.Image;
import org.zkoss.zul.Label;
import org.zkoss.zul.Space;

public class IndexController extends GenericForwardComposer {

    boolean odd = false;
    boolean odd1 = false;
    private int cnt = 1;
    private Groupbox choicesArea, pickedArea;
    private Label correctChoices;

    public void doAfterCompose(Component comp) throws Exception {


    BufferedImage newimg(boolean update, int num) {
        BufferedImage bi = new BufferedImage(150, 150, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = bi.createGraphics();
        g2d.setStroke(new BasicStroke(5));
        Line2D line = null;
        Rectangle2D retangle = null;
        if (update) {
            line = new Line2D.Double(10, 10, 130, 130);
            retangle = new Rectangle2D.Double(25, 25, 85, 85);
        } else {
            line = new Line2D.Double(10, 130, 130, 10);
            retangle = new Rectangle2D.Double(25, 25, 85, 85);
        g2d.setColor(update ? Color.cyan : Color.RED);
        g2d.setColor(update ? Color.yellow : Color.pink);
        g2d.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 18));
        g2d.drawString(Integer.toString(num), 55, 50);

        return bi;

    public void updateNextArea() {

        Image anImage;
        Space aSpace;
        List<Component> choicesAreaChildren;
        List<Component> choicesAreaKids;
        int numChoices = 4;
        String correctChoicesValue = "";

        choicesAreaChildren = choicesArea.getChildren();
        choicesAreaKids = new ArrayList<Component>();

        // copy the list to prevent ConcurrentModificationException
        for (Component comp : choicesAreaChildren) {

        // clear current choices
        for (Component comp : choicesAreaKids) {
            if ((comp.getClass() == Image.class) || (comp.getClass() == Space.class)) {

        // generate a new set of icons with the next numChoices numbers
        for (int i = 0; i < numChoices; i++) {
            anImage = new Image();
            anImage.setContent(newimg((odd1 = !odd1), cnt));

            anImage.setTooltiptext("image number: " + cnt);
            correctChoicesValue += cnt + " ";

            anImage.addEventListener(Events.ON_DOUBLE_CLICK, new EventListener() {

                public void onEvent(Event event) throws Exception {
                    DropEvent dropEvent = new DropEvent(Events.ON_DROP, pickedArea, event.getTarget(), 0, 0, 0, 0, 0);
            aSpace = new Space();

    public void onDrop$pickedArea(DropEvent evt) {
        Space aSpace;
        Image toolImg = (Image) evt.getDragged();

        move(evt.getTarget(), evt.getDragged());
        aSpace = new Space();


    private void move(Component dropTo, Component dragged) {

delete flag offensive retag edit

5 Replies

Sort by ยป oldest newest

answered 2010-12-19 16:02:55 +0800

meh gravatar image meh
57 1

I found a workaround for this problem.

I now write the BufferedImage to a file, and use setSrc rather than setContent for the Image.

link publish delete flag offensive edit

answered 2010-12-20 09:28:40 +0800

mirjalali gravatar image mirjalali
27 1

After having a look on the source code of the Image class, I found a much better workaround (till the ZK team resolves the issue in a new version).
Extend the class org.zkoss.zul.Image like this:

public class DynamicImage extends Image {

	private static long __content_counter__ = 0;
	 * This overriding is a workaround for correcting the ZK bug in dynamic image content cache.  
	public void setContent(RenderedImage image) {
		try {
			setContent(Images.encode("a"+(__content_counter__++)+".png", image));
		} catch (java.io.IOException ex) {
			throw new UiException(ex);

And from now on, use the DynamicImage class instead of Image.
If you want to use <image> tags in your zul files, do not forget to update your lang-addon.xml by adding some lines like this:



link publish delete flag offensive edit

answered 2010-12-20 15:00:19 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16

thanks for sharing.

link publish delete flag offensive edit

answered 2013-01-30 15:18:57 +0800

zippy gravatar image zippy
504 1 2

Hi, i have the same problem.

Is solved in some zk version?

link publish delete flag offensive edit

answered 2020-02-25 12:08:05 +0800

mfinis gravatar image mfinis

Hello, I ask for your support since something similar is happening to me when using the Image component since when sending the route dynamically, it shows in some cases old images that had previously been shown. I don't know if it's because of cache or what might be happening. The version of zk he used is 8.0.5. I need your support and I have reviewed everything in terms of java and handling of the component's objects.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools




Asked: 2010-12-14 16:26:03 +0800

Seen: 557 times

Last updated: Feb 25 '20

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More