2014-11-22 3 views
-1

나는 스윙에서이 응용 프로그램을 작업 중입니다. 실제로 음성으로 제어되는 것입니다. 음성 명령을 내리고 일부 동작이 수행됩니다.하지만 일단 배치되면 무한 루프 동안, 그것은 지속적으로 목소리를 검색합니다. (아이언 맨 영화의 jarvis를 묘사해야합니다.)하지만이 동안 루프가 내 GUI를 고정시킵니다. 업데이트 할 수 없습니다. 패널을 숨길 수 없으며 사운드를 재생할 수 없습니다.스윙의 무한 루프

스윙 노동자 스윙 utilitie들 shouldn, 내가 실시간 음성 인식을 필요로하는 동안 그들은 일정 시간 후 코드를 확인하기 때문에 t은

그래서 무엇을 수행 할 수 있습니다 .. 도와? 내 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. 

    } 
} 
+0

동안 (portId == 널 && portEnum.hasMoreElements()) ... portId! = null 인 동안을 의미합니까? – ha9u63ar

+1

1) 모든 소문자로 입력 한 단어는 중얼 거리는 사람의 말을 듣는 것처럼 읽기가 어렵습니다. 문장의 시작 부분에있는 대문자, I라는 단어, 'ArrayList'또는 Oracle과 같은 적절한 이름을 사용하십시오. 2) 더 빨리 도움을 받으려면 [MCVE] (http://stackoverflow.com/help/mcve) (최소 완성 입증 가능 사례) 또는 [SSCCE] (http://www.sscce.org/) (간략히, 자체 포함, 올바른 예). 3) 예를 들어 이미지를 얻는 한 가지 방법은 [이 Q & A] (http://stackoverflow.com/q/19209650/418556)에서 볼 수있는 이미지에 핫 링크하는 것입니다. –

+0

umm.no ..이 코드 부분은 정확합니다. 문제는 @hagubear – aaaaaaa

답변

2

는 기본적으로, 당신은 EDT 아닌 다른 스레드에서 무한 루프 실행이 필요합니다 코드 스케치를합니다. GUI를 업데이트하려면 언제든지 SwingUtilities.invokeLater 호출을 사용하여 EDT에서 수행하십시오. invokeLater에 GUI 업데이트를 호출하기위한 지연은 거의 눈에 띄지 않습니다. SwingUtilities.invokeLater은 폴링 메커니즘을 기반으로하지 않습니다. 그것이하는 유일한 일은 Runnable을 EDT에 게시되는 이벤트로 변환하는 것입니다. 그러면 EDT가 가능한 한 빨리 Runnable을 실행하므로 대부분의 경우 즉시 처리됩니다.

이제 스레드와 GUI간에 통신하는 방법에 대한 패턴은 "관찰자"패턴을 사용하기 만하면됩니다. 음성 인식 스레드는 어떻게 든 모델이며 UI는 해당 모델의 변경 사항을 수신합니다. 모델이 변경 될 때마다 UI가 자동으로 업데이트됩니다.

나는 그런 것의 더미보기를 만들었다. "Observer"패턴의 경우, PropertyChangeSupport을 사용했습니다. 모델의 는, I는 가끔씩 랜덤 "명령"을 생성하는 더미 스레드와 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

기본 워크 플로를 봅니다.하지만 처음으로 '관찰자'인터페이스를 사용하려고합니다. 그리고 내 머리가 너무 쑤셔서 자세한 설명을 들으려고하지 않습니다. 그렇다면 내 음성 수신 코드를 그 안에 교체하는 동안 루프와 내 gui 코드는'initui' 내부에 있고, 마치 .. 마치 .. 실행되는 것처럼 ... 그대로! – aaaaaaa

+0

@aaaaaaa 작동하지 않을 이유가 없습니다.유일한 "트릭"은 음성 인식에서 UI로 알림을받을 때 UI를 업데이트하는 코드를'invokeLater' 호출에 넣어야합니다 (UI가 EDT에서 업데이트되도록 보장). –

+0

감사합니다. .. 이제는 잘 작동하고있어. – aaaaaaa