YAIP (Yet another ImagePanel) for Java

For our current internal project, I needed a way to display images within a Java Swing application. There are probably as many solutions to this out, as there are swing programmers, but here is a quick way to get this done, that solves my two major issues:

Resizable, i.e. when the panel changes in size, the image changes along.

Integratable with NetBeans, especially with the Matisse component designer.

This worked for me:

public class ImagePanel extends JPanel {

    private Image image;
    private Image displayImage;

    public ImagePanel() {
        super();
    }

    public ImagePanel(Image image) {
        super();
        this.image = image;
        this.displayImage = image;
    }

    @Override
    public void paintComponent(Graphics g) {
        fitImage();

        while (!g.drawImage(displayImage, 0, 0, null)) {
        }
    }

    @Override
    public void setSize(Dimension d) {
        super.setSize(d);
    }

    private synchronized void fitImage() {

        if (image != null) {
            int imageHeight = image.getHeight(null);
            int imageWidth = image.getWidth(null);

            double ratio = ((double) imageHeight) / ((double) imageWidth);

            Dimension d = this.getSize();

            double height = d.getHeight();
            double width = d.getWidth();

            if (height == 0 || width == 0) {
                height = this.image.getHeight(null);
                width = this.image.getWidth(null);

            } else {
                double tempH = Math.floor(ratio * width);
                double tempW = Math.floor(height / ratio);

                if (tempH + 1 > height) {
                    width = tempW;
                } else {
                    height = tempH;
                }
            }
            displayImage = image.getScaledInstance((int) Math.floor(width), (int) Math.floor(height), Image.SCALE_DEFAULT);
        }
    }

    public Image getImage() {
        return image;
    }

    public void setImage(Image image) {
        this.image = image;
        fitImage();
    }

Note the while-loop in the paintComponent() method. Without this, you will only get partial image updates, since the drawImage() method on Graphics runs in the background. For very large images or latency sensitive applications this might be an issue, but for my application this is quite acceptable.

In order to integrate this class with NetBeans, you create a Swing JPanel with the graphical designer, and set the “Custom Creation Code” for that panel to be your ImagePanel. Within the code, you can now easily cast to ImagePanel, thus giving you the full image functionality, while not sacrificing visual design.

tags:

Leave a Reply

Your email address will not be published. Required fields are marked *