Java 摆动中的无限循环

Java 摆动中的无限循环,java,swing,Java,Swing,我正在swing中开发这个应用程序。它实际上是一个语音控制的东西…我发出语音命令并执行一些操作。但问题是,一旦它被部署,它就处于无限的while循环中,它会不断搜索语音(它应该……想象一下铁人电影中的jarvis)。。但是这个while循环冻结了我的gui。我不能更新它。不能隐藏面板,不能播放声音 摇摆工人和摇摆工具s;i don’我不能帮我,因为他们会在一段时间后检查代码,而我需要实时语音识别 那么我们能做些什么呢?我可以让我的gui与另一个java程序交互吗?像java prog一样,它将进

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

摇摆工人和摇摆工具s;i don’我不能帮我,因为他们会在一段时间后检查代码,而我需要实时语音识别

那么我们能做些什么呢?我可以让我的gui与另一个java程序交互吗?像java prog一样,它将进行语音识别并将回复传递给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.

    }
}

基本上,您需要在EDT之外的另一个线程中运行无限循环。无论何时,只要您想更新GUI,都可以在EDT上使用
SwingUtilities.invokeLater
调用进行更新。在
invokeLater
中调用GUI更新的延迟几乎不明显
SwingUtilities.invokeLater
不基于轮询机制。它所做的唯一一件事就是将
可运行的
转换为事件,然后发布到EDT上。然后,EDT将尽快执行您的
Runnable
,因此大多数情况下会立即执行

现在,对于如何在线程和GUI之间通信的模式,您可以简单地使用“观察者”模式。您的语音识别线程在某种程度上是一个模型,而您的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();
    }

}
import java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入java.beans.PropertyChangeSupport;
导入java.util.Random;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.SwingUtilities;
公共类TestThreadingAndGUI实现PropertyChangeListener{
私有JFrame;
私人标签;
私有DummyRunnable;
公共静态类DummyRunnable实现Runnable{
私有PropertyChangeSupport pcs=新PropertyChangeSupport(此);
私有字符串命令;
public void addPropertyChangeListener(PropertyChangeListener侦听器){
pcs.addPropertyChangeListener(listener);
}
@凌驾
公开募捐{
随机=新随机();
while(true){
试一试{
线程睡眠(((random.nextInt(3))+1)*1000);
}捕捉(中断异常e){
e、 printStackTrace();
}
StringBuilder sb=新的StringBuilder();
对于(int i=0;i<15;i++){
sb.append((char)('a'+random.nextInt(26));
}
setCommand(sb.toString());
}
}
公共字符串getCommand(){
返回命令;
}
私有void setCommand(字符串命令){
字符串old=this.command;
this.command=命令;
pcs.firePropertyChange(“命令”,旧,命令);
}
}
受保护的void initUI(DummyRunnable){
frame=新的JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label=新的JLabel();
标签设置水平对齐(JLabel.CENTER);
框架。添加(标签);
框架。设置尺寸(600600);
frame.setVisible(true);
this.runnable=runnable;
runnable.addPropertyChangeListener(此);
}
私有void executeCommand(){
label.setText(runnable.getCommand());
}
@凌驾
公共作废属性更改(属性更改事件evt){
if(evt.getPropertyName().equals(“命令”)){
//收到新命令(EDT之外)
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
//在EDT内更新GUI
executeCommand();
}
});
}
}
公共静态void main(字符串[]args){
final DummyRunnable runnable=新DummyRunnable();
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
TestThreadingAndGUI TestThreadingAndGUI=新的TestThreadingAndGUI();
testThreadingAndGUI.initUI(可运行);
}
});
新线程(runnable.start();
}
}

while(portId==null&&portEnum.hasMoreElements())…您是说while portId!=空?1)所有小写字母输入的单词都很难读懂,就像试图听别人喃喃自语一样。请在句子的开头使用大写字母表示单词I,并使用诸如
ArrayList
或Oracle之类的专有名称。2) 为了更快地获得更好的帮助,可以发布一个(最小完整的可验证示例)或(简短、自包含、正确的示例)。3) 例如,获取图像的一种方法是热链接到.umm.no.中看到的图像。这部分代码是正确的。while循环给了我问题@hagubear。。4) 不要阻止EDT(事件调度线程)。发生这种情况时,GUI将“冻结”。有关详细信息和修复方法,请参阅。“swing worker和swing实用程序不应该帮助我,因为它们会在一段时间后检查代码…”“非实时”可能只有几毫秒,这甚至不会被用户注意到。我看到了基本的工作流程。但我将第一次使用
observer
界面。我的头跳得太厉害了,无法进入详细的解释