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