1

这样一段代码:

private void log(String message) {
    LogBox.append(message + "\n");
}

private void log(Exception e) {
    log(e.getMessage());
}

private void ConvertButtonActionPerformed(java.awt.event.ActionEvent evt) {
    String url = UrlBox.getText();
    if (url.isEmpty()) {
        log("Empty URL");
        return;
    }
    LogBox.setText("");
    try {
        log("URL "+url+" accepted. Trying to download...");
        String content = URLConnectionReader.getText(url);
        log("Downloaded. Parsing the content...");
        //
    } catch (Exception e) {
        log(e);
    }
}

应在每次调用后立即将每条消息输出到LogBox( JTextArea) ,但仅在完成时输出。logURL ... acceptedURLConnectionReader.getText(url)

有几种方法可以立即输出:

  • Visual Basic 6 和 .NET 中的 Application.DoEvents
  • Delphi 中的 Application.ProcessMessages

有没有一些简单的方法可以立即输出?我正在研究有关 DoEvents 以及如何在 Java 中执行此操作的问题,但我认为从多线程开始学习 Java 不是正确的方法。

4

2 回答 2

5

创建一个SwingWorker进行下载:http ://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html


an 的作用ActionListener就是:监听用户动作,并通过程序对该动作做出响应。

有时,程序的响应非常快,而且只涉及 GUI。例如,在计算器应用程序中,您可以将侦听器附加到“等于”按钮,该按钮计算当前表达式的结果并将其写入文本框。这一切都可以在侦听器方法中完成(尽管您可能希望分离行为以进行测试)。

如果对用户操作的响应是启动一些长时间运行的过程,例如下载和解析文件,那么您不希望在侦听器主体中执行此操作,因为它会冻结 UI。相反,从侦听器中收集任何信息(在您的情况下为 URL 值),然后启动 aSwingWorker来处理程序的响应。

在我的评论中,我建议将所有内容getText()移到SwingWorker. 这是因为,对我来说,响应是“如果您有一个有效的 URL,请下载一个文件,并记录进度。” 正如我所看到的,测试空字符串是响应的一部分。如果您想将空字符串测试留在侦听器中,那很好,但 imo 不太可测试。

必须将调用留getText()在侦听器的主体内部,因为您只能从事件调度线程访问 Swing 组件。如果您将该调用移至工作程序,则它可能会在文本框更新自身的同时访问文本框,从而导致数据损坏。

于 2013-07-01T15:28:12.920 回答
3

阅读并发

您可能应该将 aSwingWorker用于长时间运行的任务,然后您可以publish在 GUI 可用时生成结果。

于 2013-07-01T15:28:11.897 回答