2

我是 Swing 新手,目前正在尝试在 NetBeans 中开发一个简单的 GUI 应用程序。

我想创建某种 GUI 日志系统,将应用程序正在执行的当前操作写入 TextArea。

作为一个简单的例子,我创建了一个只包含 2 个对象的 JFrame 表单:一个“开始”按钮和一个 TextArea。

当按下“开始”按钮时,它会调用某种冗长的方法,该方法应该需要一些时间(比如 10 秒)才能完成运行,并且在此方法运行时,我想将文本附加到 TextArea 中冗长的方法(当然我希望 TextArea 立即更新)。

我的问题是我找不到正确的方法。无论如何,我尝试这样做,当我按下“开始”按钮时,应用程序冻结 10 秒,而不像我想要的那样更新 TextArea。只有当方法完成时,我才能看到 TextArea 的更新。

这是一个示例代码:

private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
    try {
        for (int i = 0; i < 10; i++) {
           textArea.setText(i + "\n");
            Thread.sleep(1000);
        }
    } catch (Exception e) {}
}

在此示例中,我希望看到的是,一旦单击按钮,在接下来的 10 秒内,每秒都会在 TextArea 中添加一个新行,如下所示:

1

2

3

4

...

但我从这段代码中得到的真正结果是应用程序冻结了 10 秒,最后 TextArea 被更新并只显示数字 9。

我尝试了许多不同的方法来做到这一点,主要是使用SwingUtilities.invokeLaterSwingWorker方法,但它们都不适合我。

任何有关找到正确方法的帮助将不胜感激。

4

3 回答 3

8

1.始终保持UI在UI线程上工作,Non-UI在Non-UI线程上工作。

2.在Java GUI 应用程序中,main()方法寿命长,在调度GUI 的构建后Event Dispatcher Thread,main() 方法退出......现在它的EDT 负责处理GUI。

3.始终保留您的 EDT 线程,这是仅用于 GUI 工作的 GUI 线程。

例如:

public static void main(String[] args){


        EventQueue.invokeLater(new Runnable(){

              public void run(){

                myframe.setVisible(true);

             }

         }

  }

4.创建一个单独的Non-UI 线程来处理那个耗时的方法。

5.你可以简单地使用Java中专门引入的Thread或使用来同步UI和Non-UI线程。SwingWorker

于 2012-08-05T15:43:47.960 回答
6

就像其他答案中所述,您将要使用SwingWorker- 我建议您阅读它,因为它是一个非常有用的工具。此实现应该为您提供您在示例中寻找的内容:

您的按钮操作:

button.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent arg0) {
        new Worker().execute();
    }
});

你的摇摆工人:

public class Worker extends SwingWorker<String, String>{

    @Override
    protected String doInBackground() throws Exception {
        //This is what's called in the .execute method
        for(int i = 0; i < 10; i++){
            //This sends the results to the .process method
            publish(String.valueOf(i));
            Thread.sleep(1000);
        }
        return null;
    }

    protected void process(List<String> item) {
        //This updates the UI
        textArea.append(item + "\n");
    }
}
于 2012-08-06T04:31:21.777 回答
3

使用javax.swing.Timer类。有关详细信息,请参阅如何使用摆动计时器

于 2012-08-05T15:34:30.923 回答