1

我用 swing ui 创建了一个 java 程序。首先,当我单击一个按钮时,我遇到了一个问题,我无法单击另一个按钮。我应该等这个人完成他的任务。所以我创建了一个全局变量线程,并在动作事件中线程执行该方法。如以下代码中所述

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

我想通过使用其他按钮来停止执行该线程。我试过 t.stop(); t.destroy(); 杀死 pid 但一直以来我都无法停止执行。在我的metod execShellCmd 的实现中,我使用了一个swing worker,但我的问题仍然是如何停止执行。

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

1 回答 1

6

从您提供的代码中,您可能希望总体上阅读 Swing 中的线程,因为听起来问题是由于不了解线程模型的工作原理而引起的。

本质上,您有一个事件调度线程,应该调用所有SwingUtilities.invokeLater()Swing 操作(如果您还没有在此 EDT 上,则使用它。)但是,根本不应该在 EDT 上执行长时间运行的任务,否则(如您发现) 它会锁定 GUI,直到它们完成。

如果你想执行一个长时间运行的任务,你的思路是正确的,但你通常会使用 a SwingWorker,它允许异步执行一个长时间运行的任务,而且在任务完成时在 EDT 上提供回调.

就停止这样的线程而言,一种简单的方法是让它在执行时监视一个字段,并在您希望它停止时从 EDT 切换该字段(一个简单的操作)。不要使用该stop()方法或类似的方法,它们有很多问题(有充分的理由不推荐使用它们。)如果您使用的是,SwingWorker那么它具有内置的取消支持,使用它是明智的。

于 2013-03-06T10:29:36.230 回答