1

I created a java program with swing ui. firstly, i have a problem when i click in a button i cant click to another. i ought to wait that this one finish his task. so i created a global variable thread and in the action event the thread execute the method. as mintioned in the code below

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {

        t = new Thread() {
            private int postion;

            public void run() {
                InstallApk installapk = new InstallApk();
                int position = 0;
                String fileName = directory;
                String shellCommand = fileName;

                // for (int position =0; postion < 105;position +5) {
                jProgressBar1.setValue(InstallApk.value);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                }
                position += 5;
                // }

                jProgressBar1.setIndeterminate(true);

                installapk.execShellCmd(shellCommand);
                System.out.println("la valeur d'execution " + InstallApk.value);

                if (InstallApk.value > 3) {
                    jProgressBar1.setIndeterminate(false);
                }
            }

        };
        pid = t.getId();
        t.start();
    } 

i would like to stop the execution of this thread, by using an other button. I tried t.stop(); t.destroy(); kill pid but all the time the some result i can't stop the execution. in the implementation of my metod execShellCmd i used a swing worker but my probleme still how to stop the execution.

public static void execShellCmd(String cmd) {
        if (runningProcess != null) {
            // TODO print some suitable warning about process already running
            return;
        }
        try {

            //testPath = getPath();

            System.out.println("le chemin de travail.." +testPath);
            System.out.println(cmd);
            Runtime runtime = Runtime.getRuntime();
            process = runtime.exec(new String[] { "sh",
                    testPath + "/install.sh", cmd });
            new SwingWorker<Integer, Void>() {
                protected Integer doInBackground() {
                    // read process output first
                    BufferedReader buf = new BufferedReader(
                            new InputStreamReader(process.getInputStream()));
                    String line = "";
                    try {
                        while ((line = buf.readLine()) != null) {
                            System.out.println("exec response: " + line);
                            log = line;
                            writeToFile(line);
                            value ++;
                        }
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                     System.out.println("la valeur d'execution "+InstallApk.value);
                    // only once we've run out of output can we call waitFor
                    while (true) {
                        try {
                            return runningProcess.waitFor();
                        } catch (InterruptedException e) {
                            // do nothing, wait again
                        } finally {
                            Thread.interrupted();
                        }
                    }
                }
                protected void done() {
                    runningProcess = null;
                }
            }.execute();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
user2043602
  • 237
  • 2
  • 4
  • 15

1 Answers1

6

From the code you've supplied, you may wish to read up on threading in Swing generally, since it sounds like the problem has arisen from not having an understanding as to how the threading model works.

Essentially, you have an event dispatch thread, which all Swing operations should be called on (by using SwingUtilities.invokeLater() if you're not already on this EDT.) However, no long running tasks should execute on the EDT at all, otherwise (as you find) it locks up the GUI until they're complete.

In the case when you want to execute a long running task, you're along the right lines but you'd generally use a SwingWorker, which allows asynchronous execution of a long running task, but also provides callbacks on the EDT when the task is complete.

In terms of stopping such a thread, an easy way would be to have it monitor a field as its executing, and switch that field from the EDT (a trivial operation) when you want it to stop. Don't use the stop() method or likewise, they have many issues (they're deprecated for a good reason.) If you're using a SwingWorker then it has cancelling support built in which would be wise to use.

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
  • 1
    SwingWorker also includes canceling support, one should use that – lbalazscs Mar 06 '13 at 10:54
  • thanks, in the code that i used i implement a SwingWorker as you can see in the part that i added. and if i don't use the thread. i can't do anything else just wait the end of the execution. – user2043602 Mar 06 '13 at 11:06