从可运行对象更新 GUI [英] Updating GUI from a runnable

查看:36
本文介绍了从可运行对象更新 GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个 Swing 应用程序,其中一部分功能应该是处理和输出一些视觉和听觉文本(使用 Mary TTS).我需要一些关于 GUI 和文本处理类进行通信的最佳方式的建议.

I'm building a Swing application and one part of the functionality should be to process and output some text visually and audibly (using Mary TTS). I need some advice on the best way for the GUI and text processing classes to communicate.

GUI 类是 JPanel 的子类.其中我有一个实现 Runnable 的类,称为 LineProcesser,它准备将文本发送到音频播放器.我正在使用线程执行器来避免 EDT(这可能不是最好的方法,但它似乎达到了我想要的结果).

The GUI class is a subclass of JPanel. Within that I have a class implementing Runnable, called LineProcesser, which prepares the text to be dispatched to an audio player. I'm using a thread executor to keep this off the EDT (that may not be the best way but it seems to achieve the result I'm after).

我的目的是让 LineProcessor 遍历所有文本并在每行末尾更新 JTextArea.此外,它需要在某些点停止并等待用户输入.用户输入完成后,GUI 类应该告诉它继续处理.

My intention is for LineProcessor to run through all the text and update a JTextArea at the end of each line. Additionally it will need to halt and wait for user input at certain points. After the user input has been completed the GUI class should tell it to resume processing.

以下代码说明了我目前拥有的:

The following code illustrates what I currently have:

public class MyPanel extends JPanel {
    ExecutorService lineExecutor = Executors.newSingleThreadExecutor();
    Runnable lineProcessor = new LineProcessor();

    public class LineProcessor implements Runnable {

        private int currentLineNo = 0;

            public LineProcessor() {
            //  ...
            }

            @Override
            public void run() {
                // call getText();  
                // call playAudio();
                currentLineNo++;
            }
        }
    }

    private JButton statusLbl = new JLabel();       
    private JButton mainControlBtn = new JButton();

    private void mainControlBtnActionPerformed(ActionEvent evt) {

        if (mainControlBtn.getText().equals("Start")) {
                          lineExecutor.submit(lineProcessor);
                          mainControlBtn.setText("Running");
        }
    }
}

LineProcessor 如何通知 GUI 组件它们需要更改以及如何从 GUI 中暂停和重新启动它?我对是否需要 Swing Worker、属性/事件侦听器或其他东西感到困惑?我读过的例子有点道理,但我不知道如何将它们应用到我这里的代码中.

How can LineProcessor notify GUI components that they need to change and how can it be paused and restarted from within the GUI? I'm confused as to whether I need a Swing Worker, property/event listeners or something else? The examples I've read sort of make sense but I can't see how I can apply them to the code I have here.

推荐答案

您需要做的就是将任何 Swing 调用包装在一个 Runnable 中,并通过 SwingUtilities.invokeLater(myRunnable);SwingUtilities.invokeLater(myRunnable);.而已.不需要 SwingWorker.

All you need to do is wrap any Swing calls in a Runnable, and queue it on the EDT via SwingUtilities.invokeLater(myRunnable);. That's it. No need for a SwingWorker.

例如,

public class LineProcessor implements Runnable {
  private int currentLineNo = 0;
  Runnable LineProcessor = new LineProcessor();  // won't this cause infinite recursion?

  public LineProcessor() {
     // ...
  }

  @Override
  public void run() {
     // call getText();
     // call playAudio();
     currentLineNo++;

     SwingUtilities.invokeLater(new Runnable() {
        public void run() {
           // *** Swing code can go here ***
        }
     });
  }
}

这篇关于从可运行对象更新 GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆