【问题标题】:Infinite-while or for loop after ActionEvent not working in swing. why?ActionEvent 后的 Infinite-while 或 for 循环无法正常工作。为什么?
【发布时间】:2014-10-19 19:16:41
【问题描述】:
public void myMethod()
{
if (capture.isOpened()) {
    while (true) { //This is The main issue.
        capture.read(webcam_image);
        if (!webcam_image.empty()) {
            webcam_image = my_panel.detect(webcam_image);
            temp = my_panel.matToBufferedImage(webcam_image);
            my_panel.setimage(temp);
            my_panel.repaint();
            System.out.print("."); // It should prints "." but the above code doesn't works.
        } else {
            System.out.println(" --(!) No captured frame -- Break!");
            break;
        }
    }
}
}

这是调用上述方法的代码... 实际上它是一个可以在单击菜单时触发的 ActionEvent。

if (e.getActionCommand().equals("goLive")) {
        System.out.println("Live...");
        myMethod();
}

实际上我知道这是无限 while 循环的问题,但在这里我需要不惜一切代价设置这个条件。

【问题讨论】:

标签: java multithreading swing while-loop infinite-loop


【解决方案1】:

此类问题的确切解决方案是 Timer 类。我们可以使用下面的代码来解决这个问题。

Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            myMethod();
        }
}, 0);

感谢谷歌,oraclejava doc

【讨论】:

    【解决方案2】:

    假设 myMethod 被事件侦听器 (actionPerformed) 调用,则无限循环正在阻塞 event dispatch thread。 您可以通过使用SwingWorker 或在另一个线程上执行循环来避免这种情况:

    public void myMethod()
    {
    if (capture.isOpened()) {
        new Thread(new Runnable() { //Create a new thread and pass a Runnable with your while loop to it
            @Override public void run() {
                while (true) {
                    capture.read(webcam_image);
                    if (!webcam_image.empty()) {
                        webcam_image = my_panel.detect(webcam_image);
                        temp = my_panel.matToBufferedImage(webcam_image);
                        SwingUtilities.invokeLater(new Runnable() { //The following lines affect the GUI and must be executed on the event dispatch thread, so they should be wrapped inside a Runnable
                            @Override public void run() {
                                my_panel.setimage(temp);
                                my_panel.repaint();
                            }
                        }
                        try{
                            Thread.sleep(xxx); //consider waiting for a moment (e.g. 16ms)
                        } catch(InterruptedException e) { ... }
                        System.out.print(".");
                    } else {
                        System.out.println(" --(!) No captured frame -- Break!");
                        break;
                    }
                }
            }
        }).start(); //Let the thread loop in the background
    }
    }
    

    【讨论】:

    • 非常感谢@J4v4,但在这里我面临最终变量的问题,所有上述变量都来自方法之外,尽管我无法将它们全部设置为最终变量。 .Buddy 怎么办?
    • @Gops 这只是一个非常简单的例子。我可能错了,但是您的代码似乎不是线程安全的。我想查看整个代码以提供更好的解决方案。例如,如果您创建了一个实现 Runnable 的新类,您可以在构造函数中传递变量,则可以避免使用最终变量。
    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    相关资源
    最近更新 更多