【问题标题】:Using Swing Timer to update BufferedImage on GUI使用 Swing Timer 在 GUI 上更新 BufferedImage
【发布时间】:2015-07-20 13:22:58
【问题描述】:

我一直在尝试使用 Swing Timer 更新插入到 GUI 的 BufferedImage。 最初,我使用通过控制器实例获得的 BufferedImage 创建了 ImageIcon,然后将其添加到 JLabel(字段)。然后在 GUI 上显示当前图像。 这里是来自 GUI 类中初始代码的代码 sn-p。

JLabel field;
ImageIcon icon;
BufferedImage image = this.controller.getCameraImage();
icon = new ImageIcon(image);
field= new JLabel (icon);

现在我尝试每 x 秒获取一个 BufferedImage 。 为此,我使用了 Swing Timer 类,但不幸的是我未能成功。 我使用 ActionListener 创建了以下类,以便每 3 秒使用 getCameraImage 方法检索一个新图像。

这里是带有 ActionListener 类的 UpdateImage:

public class UpdateImage {

private JLabel label;
private Timer timer;
private Controller controller;
private int delay = 3000; // every 3 seconds
private ImageIcon icon;
private BufferedImage image;


public UpdateImage(Controller controller) throws Exception {
    this.controller = controller;

    ActionListener action = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent event) {
            try {
                System.out.println("image update");
                label = new JLabel();
                image = controller.getCameraImage();
                label.setIcon(new ImageIcon(image));
            } catch (CallError | InterruptedException e) {

                e.printStackTrace();
            }

        }

    };

    timer = new Timer(delay, action);
    timer.setInitialDelay(0);
    timer.start();

}



public JLabel getLabel() {
    return label;
}

}

在将 BufferedImage 设置为 ImageIcon 后,我使用 getLabel 方法检索它。 然后将此组件添加到 GUI。

public class GUI{
UpdateImage update;

 //more code

JLabel field;
SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                try {
                new UpdateImage(controller);
                } catch (Exception e) {

                    e.printStackTrace();
                }
            }
        });
}
field = update.getLabel( );


//more code

}

字符串“图像更新”每 3 秒根据需要在控制台上显示一次。 但图像不会显示在 GUI 上。

如果有人可以通过给我一些提示或指出我做错了什么来帮助我,我将不胜感激。

【问题讨论】:

标签: java swing user-interface


【解决方案1】:

当您使用具有相同文件名的 ImageIcon 时,图像会被缓存。您需要强制重新加载图像:

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 );
*/
                    imageLabel.setText("");
                }
                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();
            }
        });
    }
}

编辑:

您还需要Screen Image 类来执行此代码。

【讨论】:

  • 这正是我想要的。我浏览了代码,它真的帮助了我。非常感谢。最后一个问题。时间标签是必要的吗?我在没有使用它的情况下对其进行了测试,并且 GUI 甚至不会弹出。
  • 抱歉,我忘了包含指向 ScreenImage 类的链接(请参阅我刚刚添加链接的编辑)。时间标签每秒更新一次,所以我使用ScreenImage 类创建一个新图像,将图像保存到文件中,然后重新加载图像文件。如果您从此代码中删除标签,则该类甚至不会编译。我不确定为什么你的 GUI 不会弹出。即使框架不包含任何组件,您也可以显示它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
相关资源
最近更新 更多