我遗漏了一些东西,我已经创建了一个基于callable的calss,并在我的gui中创建了一个实例并在执行动作时调用它。唯一的事情是GUI没有响应,因为进程在同一个线程上运行,并且必须等待它才能访问GUI。以下是一些代码:
public class MYProject {
public static class CreateProject implements Callable<Boolean>{
private String m_url;
private String m_project;
private String m_options;
public CreateProject(String url, String project, String options){
m_url = url;
m_project = project;
m_options = options;
}
public Boolean call(){
Boolean result = true;
try {
if (os.toLowerCase().contains("windows")){
command = windowsCMD + command;
}
String line;
Process p = Runtime.getRuntime().exec(command);
InputStreamReader isr = new InputStreamReader(p.getInputStream());
BufferedReader bri = new BufferedReader(isr);
try {
while ((line = bri.readLine()) != null) {
if(line.startsWith("ERROR")){
System.out.println(line);
result = false;
break;
}
}
p.waitFor();
}
finally {
bri.close();
}
}
catch (Exception err) {
System.err.println("Unable to create project: " + err.getMessage()
+ "\n");
result = false;
}
return result;
}
}
}
并在GUI中:
private void jButtonRefreshActionPerformed(java.awt.event.ActionEvent evt) {
jTextAreaConsole.append("Creating project.\n");
MYProject.CreateProject blah = new MYProject.CreateProject("url", "project", "options");
String result = blah.call();
jTextAreaConsole.append("Project creation successful: " + result);
}
结果是进程p仍然在与gui相同的线程上运行,没有任何东西可以点击,并且jTextAreaConsole在进程完成之前不会更新。任何人都可以提供一些关于我应该如何实现这一点的建议吗?
答案 0 :(得分:3)
为长时间运行的任务实施SwingWorker
。有关详细信息,请参阅Concurrency in Swing。
答案 1 :(得分:2)
结果是进程p仍然在与...相同的线程上运行 gui并没有可点击的jTextAreaConsole
是的,它正在完成p.waitFor();在你的代码中
waitFor()
如果需要,使当前线程等待,直到此Process对象表示的进程终止。
这
您可能希望使用像@Andrew Thompson发布的SwingWorker 或者,您可以实现Runnable的run方法并在新线程中启动它 甚至使用像@hoaz发布的Executor类
要使callable在separete线程中运行,您需要使用Executors
答案 2 :(得分:0)
您应该使用Executor
在Callable
单独运行Thread
个实例。
Executor executor = Executors.newSingleThreadExecutor();
executor.submit(blah);
...
executor.shutdown(); // free resources
请注意,您应该创建一次执行程序并在程序退出时将其销毁。否则你可能会泄漏资源。