Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中执行进程而不冻结JFrame_Java_Swing_Swingworker - Fatal编程技术网

在Java中执行进程而不冻结JFrame

在Java中执行进程而不冻结JFrame,java,swing,swingworker,Java,Swing,Swingworker,如何在Java中执行进程而不冻结程序? 我试过使用SwingWorker,但我还不太明白它是如何工作的 我还有别的方法可以做到这一点吗?我想在我的JDroidLib中使用类似的东西。有关完整的源代码,请查看GitHub: 提前谢谢 编辑: 谢谢你的回答。但是我有一个有几个方法的类(好吧,它不止一个类,但是你明白我的意思);我如何使用SwingWorker与他们互动 以下是其中一个类: /** * * @author Simon */ public abstract class Co

如何在Java中执行进程而不冻结程序? 我试过使用SwingWorker,但我还不太明白它是如何工作的

我还有别的方法可以做到这一点吗?我想在我的JDroidLib中使用类似的东西。有关完整的源代码,请查看GitHub:

提前谢谢

编辑:

谢谢你的回答。但是我有一个有几个方法的类(好吧,它不止一个类,但是你明白我的意思);我如何使用SwingWorker与他们互动

以下是其中一个类:

/**
 *
 * @author Simon
 */
    public abstract class Command extends SwingWorker {

    BufferedReader prReader = null;
    ProcessBuilder process = null;
    Process pr = null;
    Date timeNow = new Date();
    String osName = System.getProperty("os.name");

    public void executeProcessNoReturn(String _process, String arg) throws IOException {
        process = new ProcessBuilder(_process, arg);
        pr = process.start();
    }

     public String executeProcessReturnLastLine(String _process, String arg) throws IOException {
        process = new ProcessBuilder(_process, arg);
        pr = process.start();
        prReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
        String line;
        while ((line = prReader.readLine()) != null) {
            // Wait for input to end.
        }
        return line;
    }

    public StringBuilder executeProcessReturnAllOutput(String _process, String arg) throws IOException {
        process = new ProcessBuilder(_process, arg);
        pr = process.start();
        prReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
        StringBuilder output = null;
        String line;
        while ((line = prReader.readLine()) != null) {
            output.append(line);
        }
        return output;
    }

    public boolean isProcessRunning(String processName) throws IOException {
        boolean value = false;
        if (osName.equals("Linux") | osName.contains("Mac")) {
            process = new ProcessBuilder("ps", "-e");
            pr = process.start();
            String line;
            prReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
            while ((line = prReader.readLine()) != null) {
                if (line.contains(processName)) { value = true; break; }
            }
        } else {
            String winDir = System.getenv("windir") + "/System32/tasklist.exe";
            process = new ProcessBuilder(winDir);
            pr = process.start();
            String line;
            prReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
            while ((line = prReader.readLine()) != null) {
            if (line.contains(processName)) { value = true; break; }
            }
        }

        return value;

    }

     public String executeProcessReturnError(String processName, String arg) throws IOException {
        process = new ProcessBuilder(processName, arg);
        process.redirectError();
        pr = process.start();
        prReader = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
        String line;
        String output = "";
        while ((line = prReader.readLine()) != null) {
        output += line + "\n";
        }
        return output;
    }
}

您需要以单独的方式运行代码。在程序中运行和协调多条代码路径的关键字是“并发”:

多线程代码可能会变得非常棘手且难以调试,但Java提供了一些更高级别的抽象/概念,使得使用多线程代码时更不容易出错

看看这些概念的软件包


由于使用AWT/Swing时必然会遇到多线程问题,因此有一些实用程序类/方法专门用于促进图形应用程序中的多线程处理。是其中之一(另一个是例如)。熟悉它们是一个好主意,它们可以让您的生活更轻松,尤其是对于那些长度刚好足以冻结GUI的简单任务。

您需要以单独的方式运行代码。在程序中运行和协调多条代码路径的关键字是“并发”:

多线程代码可能会变得非常棘手且难以调试,但Java提供了一些更高级别的抽象/概念,使得使用多线程代码时更不容易出错

看看这些概念的软件包


由于使用AWT/Swing时必然会遇到多线程问题,因此有一些实用程序类/方法专门用于促进图形应用程序中的多线程处理。是其中之一(另一个是例如)。熟悉它们是个好主意,它们可以让你的生活更轻松,特别是对于那些简单的任务,这些任务的长度刚好足以冻结GUI。

是的,你可以使用一个
SwingWorker
这个想法是,一个需要花费大量时间的任务可以在一个单独的线程(后台线程)中运行然后你不阻塞你的gui,你的JFrame也不会冻结。这是一个我非常喜欢的完整例子

基本上,作为一个示例,您创建了自己的类,该类扩展了
SwingWorker
override
doInBackground

注: 您可以像普通类一样拥有字段

例如:

class Worker extends SwingWorker<Void, String> {
    private SomeClass businessDelegate;    
    private JLabel label;

    @Override
    protected Void doInBackground() throws Exception {
       //here you make heavy task this is running in another thread not in EDT
        businessDelegate.callSomeService();
        setProgress(30); // this is if you want to use with a progressBar
        businessDelegate.saveToSomeDataBase();
        publish("Processes where saved");
        return null;
    }

    @Override
    protected void process(List<String> chunks){
       //this is executed in EDT you can update a label for example
       label.setText(chunks.toString());
    }

   //add setters for label and businessDelegate    
}

是的,你可以使用一个
SwingWorker
这个想法是,一个在单独的线程(后台线程)中运行了很长时间的任务,那么你就不会阻塞你的gui,你的JFrame也不会冻结。这是一个我非常喜欢的完整例子

基本上,作为一个示例,您创建了自己的类,该类扩展了
SwingWorker
override
doInBackground

注: 您可以像普通类一样拥有字段

例如:

class Worker extends SwingWorker<Void, String> {
    private SomeClass businessDelegate;    
    private JLabel label;

    @Override
    protected Void doInBackground() throws Exception {
       //here you make heavy task this is running in another thread not in EDT
        businessDelegate.callSomeService();
        setProgress(30); // this is if you want to use with a progressBar
        businessDelegate.saveToSomeDataBase();
        publish("Processes where saved");
        return null;
    }

    @Override
    protected void process(List<String> chunks){
       //this is executed in EDT you can update a label for example
       label.setText(chunks.toString());
    }

   //add setters for label and businessDelegate    
}
如果您正在使用Swing,请使用以下方法

既然你提到你不明白它是如何工作的,我就给你一个简单的解释

Swing事件处理代码在中完成。因此,如果用户单击一个按钮(比如从服务器获取数据并在窗口中显示数据的更新按钮),则该按钮的ActionListener将在事件调度线程中调用

如果在同一线程中获取数据,则UI将冻结,因为它无法处理任何事件(您正在事件分派线程中运行代码)

因此,您应该在单独的线程中获取数据。但是在获取数据之后,应该将其设置为事件分派线程中的视图

秋千工人让你很容易做到这一点。您将繁重的任务放在
doInBackground
方法中(在本例中是获取数据),并从该方法返回繁重任务的输出(在本例中是数据)

在swing worker的
done
方法中,您调用
get
方法,该方法将为您提供
doInBackground
方法中返回的数据。在这里,使用新数据更新视图(例如,将数据添加到TableModel)

现在在swing worker上调用
exectue
时,它将负责在单独的线程(不是事件分派线程)中运行
doInBackground
,并在事件分派线程中运行
done
方法

因此,通过使用SwingWorker,您不必担心在EDT中处理UI事件的内部问题,也不必担心在另一个线程中处理耗时的任务。

如果您使用Swing,这是一种方法

既然你提到你不明白它是如何工作的,我就给你一个简单的解释

Swing事件处理代码在中完成。因此,如果用户单击一个按钮(比如从服务器获取数据并在窗口中显示数据的更新按钮),则该按钮的ActionListener将在事件调度线程中调用

如果在同一线程中获取数据,则UI将冻结,因为它无法处理任何事件(您正在事件分派线程中运行代码)

因此,您应该在单独的线程中获取数据。但是在获取数据之后,应该将其设置为事件分派线程中的视图

秋千工人让你很容易做到这一点。您将繁重的任务放在
doInBackground
方法中(在本例中是获取数据),并从该方法返回繁重任务的输出(在本例中是数据)

在swing worker的
done
方法中,您调用
get
方法,该方法将为您提供
doInBackground
方法中返回的数据。在这里,您将使用新数据更新视图(例如添加