摆动中的无限循环

时间:2014-11-22 12:43:00

标签: java swing

我正在研究这个应用程序。它实际上是一个语音控制的东西...我发出语音命令并执行了一些动作。但事实是,一旦它被部署,它就在无限循环中,它不断搜索声音(它应该......想象一下铁人电影的jarvis)..但是这个循环冻结了我的gui.I无法更新它。不能隐藏面板,不能播放声音。

摇摆工作者并摇摆 utilitie s不应该帮助我,因为他们在一段时间后检查代码,而我需要实时语音识别..

那么可以做些什么呢?我可以让我的gui与另一个java程序交互吗?像java编程一样会进行语音识别并将回复传递给gui?

这是代码草图

class{
    main(){
    new class()
}

class(){
    frames + content pane initialized
    mousePresssed()
    {
        ///the while loop starts here and looks for voice commands..any gui update code doesnt work here..while it detects the voice fine..continuously.

    }
}

1 个答案:

答案 0 :(得分:2)

基本上,你需要让你的无限循环运行在另一个线程而不是EDT。每当您想要更新GUI时,请使用SwingUtilities.invokeLater调用在EDT上进行更新。在invokeLater中调用GUI更新的延迟几乎不会引起注意。 SwingUtilities.invokeLater不是基于轮询机制。它唯一能做的就是将Runnable转换为一个事件,然后在EDT上发布。然后,EDT将尽快执行您的Runnable,大部分时间都会立即执行。

现在有关如何在Thread和GUI之间进行通信的模式,您可以简单地使用“Observer”模式。您的语音识别线程在某种程度上是一个模型,您的UI只是监听该模型的变化。每当模型发生变化时,UI都会自行更新。

我做了一个虚构的例子。对于“观察者”模式,我使用了PropertyChangeSupport。 对于模型,我创建了一个虚拟线程,每隔一段时间就生成一个随机的“命令”,UI会相应地更新自己:

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class TestThreadingAndGUI implements PropertyChangeListener {

    private JFrame frame;

    private JLabel label;

    private DummyRunnable runnable;

    public static class DummyRunnable implements Runnable {

        private PropertyChangeSupport pcs = new PropertyChangeSupport(this);

        private String command;

        public void addPropertyChangeListener(PropertyChangeListener listener) {
            pcs.addPropertyChangeListener(listener);
        }

        @Override
        public void run() {
            Random random = new Random();
            while (true) {
                try {
                    Thread.sleep(((random.nextInt(3)) + 1) * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 15; i++) {
                    sb.append((char) ('a' + random.nextInt(26)));
                }
                setCommand(sb.toString());
            }
        }

        public String getCommand() {
            return command;
        }

        private void setCommand(String command) {
            String old = this.command;
            this.command = command;
            pcs.firePropertyChange("command", old, command);
        }
    }

    protected void initUI(DummyRunnable runnable) {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        label = new JLabel();
        label.setHorizontalAlignment(JLabel.CENTER);
        frame.add(label);
        frame.setSize(600, 600);
        frame.setVisible(true);
        this.runnable = runnable;
        runnable.addPropertyChangeListener(this);
    }

    private void executeCommand() {
        label.setText(runnable.getCommand());
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (evt.getPropertyName().equals("command")) {
            // Received new command (outside EDT)
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    // Updating GUI inside EDT
                    executeCommand();
                }
            });
        }
    }

    public static void main(String[] args) {
        final DummyRunnable runnable = new DummyRunnable();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TestThreadingAndGUI testThreadingAndGUI = new TestThreadingAndGUI();
                testThreadingAndGUI.initUI(runnable);

            }
        });
        new Thread(runnable).start();
    }

}