kurisuwow
kurisuwow

Reputation: 3

refreshing/reloading image in a Java Application (Swing)

I have made a programm to take a snapshot from the WebCam (via OpenCV) and safes it to the Project:

Colordetection
|__src
|    |
|   main.java
|
| Snapshot.png

Now I would like to refresh the taken snapshot, everytime I re-take one and repaint it.

String imgText = "Snapshot.png";

JPanel panelScreenshot = new JPanel();
panelScreenshot.setBorder(new TitledBorder(null, "Screenshot", TitledBorder.LEADING, TitledBorder.TOP, null, null));
panelScreenshot.setBounds(10, 11, 667, 543);
panelDisplay.add(panelScreenshot);
panelScreenshot.setLayout(null);

JLabel lblScreenshot = new JLabel();
lblScreenshot.setIcon(new ImageIcon(imgText));
lblScreenshot.setBounds(10, 21, 640, 480);
panelScreenshot.add(lblScreenshot);

JButton btnScreenshot = new JButton("Screenshot");
btnScreenshot.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {              


    VideoCapture cap = new VideoCapture(0);

    if(!cap.isOpened()){
      System.out.println("Webcam not Found");

      } 
      else 
      {
      System.out.println("Found Webcam:" + cap.toString());

      Mat frame = new Mat();
      cap.retrieve(frame);

      try {
          Thread.sleep(500);
          Highgui.imwrite("Snapshot.png", frame);

          lblScreenshot.repaint();                  

          } 
          catch (Exception e1) {
            e1.printStackTrace();

      }
      cap.release();                    
    }       
  }
});

The Problem is, it doesn't repaint/refresh as I want to, only if I restart the programm, the new screenshot is there.

I also tryied it with:

ImageIcon icon = new ImageIcon(main.class.getResource("Snapshot.png"));

and changed the paths etc. but it didnt help.

does anyone has a clue?

thanks.

Upvotes: 0

Views: 1435

Answers (2)

camickr
camickr

Reputation: 324108

The image is cached by the ImageIcon so you can either:

  1. flush the image, to force the reload
  2. use ImageIO to reread the image

Simple example:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;
import java.net.*;

public class ImageReload extends JPanel implements ActionListener
{
    JLabel timeLabel;
    JLabel imageLabel;
    ImageIcon icon = new ImageIcon("timeLabel.jpg");

    public ImageReload()
    {
        setLayout( new BorderLayout() );

        timeLabel = new JLabel( new Date().toString() );
        imageLabel = new JLabel( timeLabel.getText() );

        add(timeLabel, BorderLayout.NORTH);
        add(imageLabel, BorderLayout.SOUTH);

        javax.swing.Timer timer = new javax.swing.Timer(1000, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        timeLabel.setText( new Date().toString() );

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    String imageName = "timeLabel.jpg";
                    BufferedImage image = ScreenImage.createImage(timeLabel);
                    ScreenImage.writeImage(image, imageName);

                    //  This works using ImageIO

//                  imageLabel.setIcon( new ImageIcon(ImageIO.read( new File(imageName) ) ) );

                    //  Or you can flush the image

                    ImageIcon icon = new ImageIcon(imageName);
                    icon.getImage().flush();
                    imageLabel.setIcon( icon );
                }
                catch(Exception e)
                {
                    System.out.println( e );
                }
            }
        });
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new ImageReload() );
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

This example also requires the Screen Image class to dynamically regenerated the image.

Upvotes: 1

Robin
Robin

Reputation: 36601

Never, ever, call Thread.sleep on the EDT. This freezes up your whole UI. Swing is single-thread, so if you make that thread sleep the whole UI is frozen

That being said, the reason is that the icon is only loaded once. It does not matter that the actual image on disk changes. You need to call

lblScreenshot.setIcon(new ImageIcon(imgText));

again after you have replaced the image on disc. This will reload the image.

Upvotes: 1

Related Questions