Domanda

Im missing something, I've created a calss based on callable and in my gui creating an instance and calling it when a action is performed. the only thing is that the GUI is unresponsive as the process is running on the same thread and has to wait for it to finish before I can access the GUI. Here is some of the Code:

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;
    }
}
}

and in the 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);
}

The result being Process p is still running on the same thread as the gui and nothing is clickable and the jTextAreaConsole doesnt update until after the process has finished. Can any one offer some advice on how I should be implementing this?

È stato utile?

Soluzione 2

The result being Process p is still running on the same thread as the gui and nothing is clickable and the jTextAreaConsole

Yes it is doing exactly what p.waitFor(); in your code

waitFor()

Causes the current thread to wait, if necessary, until the process represented by this Process object has terminated.

from

Process Class

You might want to use SwingWorker like @Andrew Thompson posted Or you can implement Runnable´s run method and start it in a new thread Or even using the Executor class like @hoaz posted

For the callable to run in a separete thread you need to use Executors

Altri suggerimenti

Implement a SwingWorker for long running tasks. See Concurrency in Swing for more details.

You should use Executor to run your Callable instance in separate Thread.

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

Note that you should create executor once and destroy it when your program quits. Otherwise you may leak resources.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top