Java Callable线程摆动gui

时间:2012-12-13 15:53:44

标签: java multithreading swing user-interface event-dispatching

我遗漏了一些东西,我已经创建了一个基于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在进程完成之前不会更新。任何人都可以提供一些关于我应该如何实现这一点的建议吗?

3 个答案:

答案 0 :(得分:3)

为长时间运行的任务实施SwingWorker。有关详细信息,请参阅Concurrency in Swing

答案 1 :(得分:2)

  

结果是进程p仍然在与...相同的线程上运行   gui并没有可点击的jTextAreaConsole

是的,它正在完成p.waitFor();在你的代码中

waitFor()

如果需要,使当前线程等待,直到此Process对象表示的进程终止。

Process Class

您可能希望使用像@Andrew Thompson发布的SwingWorker 或者,您可以实现Runnable的run方法并在新线程中启动它 甚至使用像@hoaz发布的Executor类

要使callable在separete线程中运行,您需要使用Executors

答案 2 :(得分:0)

您应该使用ExecutorCallable单独运行Thread个实例。

Executor executor = Executors.newSingleThreadExecutor();
executor.submit(blah);
...
executor.shutdown(); // free resources

请注意,您应该创建一次执行程序并在程序退出时将其销毁。否则你可能会泄漏资源。