2014-11-22 36 views
-1

我正在挥杆这个应用程序。它实际上是一个语音控制thingy ...我给语音命令和一些行动执行。但事情是,一旦它被部署,它是在一个无限的循环,它不断地搜索声音(它应该......设想铁人电影的jarvis)..但是这个while循环冻结了我的gui.I无法更新它。可以不隐藏面板,不能播放声音。无限循环在挥杆

摆动工人和摆动utilitie小号不应该;吨帮我,因为他们检查一定时间后的代码,而我需要实时语音识别..

那么,什么可以做什么?我可以让我的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. 

    } 
} 
+0

而(端口ID == NULL && portEnum.hasMoreElements())...你的意思是当portId!= null? – ha9u63ar 2014-11-22 12:47:31

+1

1)以小写字母输入的单词难以阅读,比如试图听别人嘟someone。请在句子的开头使用大写字母,单词I以及诸如'ArrayList'或Oracle的专有名称。 2)为了更快地获得更好的帮助,请发布[MCVE](http://stackoverflow.com/help/mcve)(最小完整可验证示例)或[SSCCE](http://www.sscce.org/)(简称,自包含,正确的例子)。 3)获取图像的一种方法是通过[本问答](http://stackoverflow.com/q/19209650/418556)中的图像进行热链接。 – 2014-11-22 12:53:09

+0

umm.no..这是代码的一部分是正确的..它是给我的问题@hagubear – aaaaaaa 2014-11-22 12:54:20

回答

2

基本上,你需要让你的无限循环运行在另一个线程比EDT。每当你想更新你的图形用户界面,请在EDT上使用SwingUtilities.invokeLater调用。调用invokeLater中的GUI更新的延迟几乎不会引起注意。 SwingUtilities.invokeLater不基于轮询机制。它唯一做的事情就是将Runnable转换成一个事件,然后发布到EDT上。美国东部时间将尽快执行您的Runnable,所以大部分时间,即刻。

现在要了解如何在线程和GUI之间进行通信的模式,您可以简单地使用“Observer”模式。你的语音识别线程在某种程度上是一个模型,你的用户界面只是监听这个模型的变化。只要模型发生变化,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(); 
    } 

} 
+0

我看到了基本的工作流程,但是我第一次使用'observer'界面。我的脑袋跳动得太厉害了,无法详细解释。所以,如果要替换我的语音接收代码,循环和我的gui代码在'initUI'里面,让所有的东西都像它一样。完全像它一样。它会运行吗? – aaaaaaa 2014-11-22 14:09:16

+0

@aaaaaaa没有理由不工作。唯一的“窍门”是,当你从你的语音识别通知你的用户界面时,你需要把更新UI的代码放在'invokeLater'调用中(以确保用户界面在EDT上更新) – 2014-11-22 17:17:15

+0

谢谢。 ..现在工作正常... – aaaaaaa 2014-11-22 17:26:51