Custom Cell Rendering prevent loading image in getListCellRendererComponent()

127 views Asked by At

I have a JList that is displaying a custom object (Frog) using a custom cell renderer.

frogList = new JList<Frog>();
frogModel = new DefaultListModel<Frog>();
frogList.setModel(frogModel);
frogList.setCellRenderer(new FrogBrowserCellRenderer());
//add frogs...

The frog objects contains a list of images, and I have my list pick the latest one to display. It's in a thumbnail file, so I can read it into memory and display it. However I know that the JList re-renders every time the window moves or the window needs redrawn which is really bad for performance and just not good design. The issue I have is that this list is dynamic so I cannot simply load all images at startup because users can add them at runtime and it'll auto update the list.

Some people mentioned loading the image into memory in the constructor and setting it in the getListCellRendererComponent() method but that doesn't appear to be possible because it only creates one cell renderer and uses it for everything in the list. I also verified this by printing out the constructor method. Since I will have a list of frogs with all different images this doesn't really make sense.

Here is the code I am using to create the thumbnail right now.

public Image createListThumbnail() {
    try {
        Image returnImg = null;
        //get latest frog image
        SiteImage img = frog.getLatestImage();
        BufferedImage src = ImageIO.read(new File(XMLFrogDatabase.getImagesFolder()+img.getImageFileName()));
        BufferedImage thumbnail = Scalr.resize(src, Scalr.Method.SPEED, Scalr.Mode.FIT_TO_WIDTH, 200, 150, Scalr.OP_ANTIALIAS);
        if (!frog.isFullySearchable()){
            ImageFilter filter = new GrayFilter(true, 30);  
            ImageProducer producer = new FilteredImageSource(thumbnail.getSource(), filter);  
            returnImg = Toolkit.getDefaultToolkit().createImage(producer);  
        }
        return returnImg;
    } catch (IOException e) {
        IdentiFrog.LOGGER.writeExceptionWithMessage("Unable to generate thumbnail for image (in memory).", e);
    }
    return null;
}

I call this method in my getListCellRendererComponent() which I know causes terrible performance but I don't understand how to cache it in memory for multiple frogs and also use only one object. Perhaps an image map? I can't seem to find any solid evidence of a proper way to do this.

0

There are 0 answers