java - 在外部 python 命令完成在 java 中运行之前什么都不会发生
问题描述
我有一个logText(String text)
功能,它基本上在文本区域中显示一些文本。在运行外部 python 命令之前,我需要显示一些文本。但是文本是在执行外部 python 命令后显示的。这是我的代码。
logText("Please Wait Until The Testing Is Finished");
logText("Starting Testing...");
String command = "python3 python/Predict.py";
try {
String line;
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
error.close();
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
input.close();
OutputStream outputStream = process.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.println();
printStream.flush();
printStream.close();
logText("Images Created At Output Directory");
logText("Testing Completed");
} catch (IOException ex) {
Logger.getLogger(MasterFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(MasterFrame.class.getName()).log(Level.SEVERE, null, ex);
}
我的logText()
职能。
private void logText(String logText) {
if (logArea.getText().equals("")) {
logArea.setText(">>> " + logText);
} else {
logArea.append(System.lineSeparator() + ">>> " + logText);
}
}
如何在执行 python 命令之前在文本区域中显示文本?
解决方案
您正在做的是在 GUI 线程上运行长时间运行的代码并因此冻结主线程的经典示例。解决方案与往常一样(无论是哪种语言或框架):在后台线程中运行长时间运行的工作,例如 new Thread(...) 或 SwingWorker。
例如:
logText("Please Wait Until The Testing Is Finished");
logText("Starting Testing...");
String command = "python3 python/Predict.py";
new Thread(new Runnable() {
public void run() {
try {
String line;
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
error.close();
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
input.close();
OutputStream outputStream = process.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.println();
printStream.flush();
printStream.close();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
// event dispatch thread
logText("Images Created At Output Directory");
logText("Testing Completed");
}
});
} catch (IOException ex) {
Logger.getLogger(MasterFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(MasterFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();
ps 正如您在评论中看到的那样,新线程中的最后两个命令需要使用SwingUtilities.invokeLater(...)
.
推荐阅读
- c# - C# 检测最大值并列出所有获取的元素
- php - $file->isValid() 在 laravel 4.2 中返回 false
- javascript - 防止在使用 ajax 分页导航时将上一页 CSS 应用到下一页
- objective-c - FSEventStreamCreateRelativeToDevice:如何获取 deviceID 的根文件夹?
- c# - 如何解决“已经有一个打开的数据阅读器与此连接关联”
- python - SQLAlchemy:禁用延迟加载并仅在 join() 上加载对象
- behat - 如何在 Behat / Mink 中从测试用例/场景中分离数据
- python - 不明白这个“SQL 语句没有足够的参数”错误
- paypal - 如何解释贝宝账单协议的创建?
- html - 如何在 Bootstrap 3 中设置 DIV 的响应高度我的代码附加?