这样一段代码:
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
(log
),但仅在URL ... accepted
完成时输出URLConnectionReader.getText(url)
。
有几种方法可以立即输出:
有一些简单的方法可以立即输出吗?我正在研究有关DoEvents以及如何在Java中执行此操作的问题,但我认为从多线程开始学习Java并不是一种正确的方法。
答案 0 :(得分:5)
创建SwingWorker
进行下载:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
ActionListener
的作用就是:监听用户操作,并通过程序启动对该操作的响应。
有时,程序的响应非常快,只涉及GUI。例如,在计算器应用程序中,您可以将一个监听器附加到" equals"用于计算当前表达式结果并将其写入文本框的按钮。这可以在侦听器方法中完成(尽管您可能希望将行为分开以进行测试)。
如果对用户操作的响应是启动一些长时间运行的过程,例如下载和解析文件,那么您不希望在侦听器主体中执行此操作,因为它将冻结UI。相反,从侦听器中收集任何信息(在您的情况下,URL值),然后启动SwingWorker
来处理程序的响应。
在我的评论中,我建议将getText()
之后的所有内容移至SwingWorker
。这是因为,对我来说,如果你有一个有效的URL,响应是#34;下载一个文件,然后记录进度。"正如我所看到的,测试空字符串是该响应的一部分。如果你想把空字符串测试留在听众中,那很好,但是它不太可测试。
您必须将getText()
的调用留在侦听器主体内,因为您只能从事件调度线程访问Swing组件。如果您将该调用移动到该worker中,那么它可能会在文本框自行更新的同时访问该文本框,从而导致数据损坏。
答案 1 :(得分:3)
阅读Concurrency。
您可能应该使用SwingWorker
来执行长时间运行的任务,然后您可以{GUI} {}获得结果。