SwingWorker锁定GUI(不成功)JLabel图标更新

时间:2011-07-01 11:43:35

标签: java multithreading swing user-interface swingworker

好吧我真的很难解锁由于单独的SwingWorker线程而被锁定的GUI。基本上我的程序做了什么:初始化网络摄像头,然后抓取单帧并将其显示为JLabel图标(单击抓取+显示按钮点击很容易,但是我在连续进行此类操作以进行一些图像处理方面存在巨大困难) 。我的目标是获得这样的结果:

抓取框架 - >处理它 - >显示为Jlabel的ImageIcon> ...重复抓取框架> ...

我需要在网络摄像头流式传输时获得结果,因此我使用了SwingWorker publishprocess。在我的代码中,“处理部分”不包括在内,因为没有必要,因为我甚至无法获得适当的连续帧抓取。一般来说,我的后台线程永远不会完成,除非取消(这就是假设,因为我希望以每秒最大帧数尽快处理图像 - 除非我应该以其他方式做到这一点? - 我猜单帧抓取和过程的单独线程会由于我的目标是获得10+ FPS,这是一个坏主意。我知道我的SwingWorker线程工作,因为我做了测试将连续图像保存到C:\,它确实有效,但我的GUI仍然被锁定,但至少我知道线程正在运行并抓取帧。

一般来说我有两个问题:

  • 没有JLabel图标更新
  • 锁定GUI

我的SwingWorker代码:

private class FrameStream extends SwingWorker<Void, BufferedImage> { 
    @Override
    protected Void doInBackground() throws InterruptedException{
        BufferedImage processedImage = null;

        while (!isCancelled()) {
            processedImage = getPIC_COLOR(player);
            publish(processedImage);

            Thread.sleep(5000); // i made such delay to check whether program is not "choking" with data, but its not the case, without this delay everthing is the same
        }            
        return null;
    }

    @Override
    protected void process(List<BufferedImage> mystuff) {
        Iterator it = mystuff.iterator(); 

        while (it.hasNext()) {
            img_field.setIcon(new ImageIcon(mystuff.get(mystuff.size()-1)));
        }
    }

    @Override
    protected void done() {            
        infoBAR.setText("FINISHED");
    }
}

我非常绝望,我完全根据教程示例重写我的代码:Flipper,因为你可以看到它是非常相似的。我之前的所有努力也锁定了gui所以尝试了“教程”,尽管如此它没有用,这很可惜。我陷入了死胡同,因为我不知道如何解决这个问题。我迫切希望得到帮助,因为你可以看到它看起来与教程完全相同,也许其他原因导致问题:MY FULL CODE

请帮忙,我自己无法解决。

4 个答案:

答案 0 :(得分:4)

对我来说有点不同的是你的处理方法。您可能希望迭代所有图像,而不是指定最后一个图像:

  @Override
  protected void process(List<BufferedImage> mystuff) {
     for (BufferedImage bImage : mystuff) {
        img_field.setIcon(new ImageIcon(bImage));
     }
  }

我不确定这是否会产生重大影响,但我相信这就是应该如何编写流程。另一个想法 - 如果BufferedImages很大,你可能希望在后台线程中创建ImageIcon并发布ImageIcon而不是BufferedImage。

答案 1 :(得分:3)

没有什么是突出的问题。我建议进一步调试的步骤。

不要使用循环和处理方法,只需拉一帧并将Icon设置一次。在尝试使其循环之前,您需要使其正常工作。您的应用程序应该能够将图标设置为不会突出显示问题的事实。

其次,因为你的GUI已经锁定,所以EDT上仍然会发生一些事情。尝试,运行探查器或在代码中添加System.out.println以查找GUI被锁定时正在运行的内容。

最后,请确保您不需要重新绘制,重新验证Label的容器以使图像可见。

答案 2 :(得分:1)

嗯,如果我读到你关于这个问题的last post,可能会有很多错误(我看到你的代码),这与SwingWorker无关,另一个example只需使用JButton#setBackground()

替换Icon or ImageIcon的更改颜色

答案 3 :(得分:0)

您是否尝试设置标签以观察图像图标?

icon.setImageObserver(label);