当前位置: 首页 > 面试题库 >

在Java中执行过程而不会冻结JFrame

魏熠彤
2023-03-14
问题内容

如何在不冻结程序的情况下用Java执行进程?我已经尝试过使用SwingWorker,但是我还不太了解它是如何工作的。

我还有其他方法可以做到这一点吗?我想在我的JDroidLib中使用类似的东西。有关完整的源代码,请查看GitHub:http
:
//github.com/Team-M4gkBeatz/JDroidLib

提前致谢!

编辑:

感谢您的回答。但是我有一个带有几种方法的类(嗯,它不止一个类,但是你明白我的意思)。如何使用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;
    }
}

问题答案:

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

基本上以示例为例,您将创建自己的扩展SwingWorker 覆盖的类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    
}

您还了解了process(..) publish(..)done()

并在您的客户端代码中放入。

SwingWorker<Void,String> myWorker = new Worker();
myWorker.execute();


 类似资料:
  • 问题内容: 我为我的一个脚本创建了一个小GUI。一切都很好。 当我单击一个按钮时,它会启动一个很大的功能,该功能正在解析某些网站中的许多数据。 但是,一旦我单击了Button,程序就会冻结,直到该功能完全运行为止。一切正常,但是为什么我的GUI在执行功能时冻结了。我想打印一个进度条,但这是不可能的。 这是程序的一部分: 在执行Module_1.main()时,我无法执行任何操作//打印任何内容…

  • 问题内容: 我在执行后台任务时使JavaFX UI保持活动状态时遇到问题。我已经设置了这个非常简单的代码- 我希望发生的事情是让进度条每1秒钟更新一次,直到任务完成。而是,UI完全冻结10秒钟,之后进度条显示为完成。明确地说- 问题不仅在于所有更新最终一次出现,而且UI直到那时都完全没有响应。 我已经阅读了有关此主题的其他任何问题,但找不到答案。我究竟做错了什么? 谢谢。 问题答案: 使用 sta

  • 我已经为我的一个脚本创建了一个小GUI。一切进展顺利。 当我点击一个按钮时,它会启动一个大功能,解析一些网站的大量数据。 但一旦我点击了按钮,程序就会冻结,直到函数完全运行。一切正常,但为什么我的GUI在函数执行过程中会冻结。我想打印一个小进度条,但这是不可能的。 以下是该计划的一部分: 在执行模块_1期间,我无法执行/打印任何内容。main()。。。GUI完全冻结。 模块1。main()函数是一

  • 所以,我的问题是,我正在尝试为我的应用程序进行单元测试。我有两个服务,我们叫它们Foo和Bar,Foo只是Bar的代理。 因此,Foo服务的路由器如下所示: 向Bar服务发出请求的处理程序如下所示: 当我这样写测试时: 它永远冻结了......嗯,我想这是因为它周围的一些协程魔法,但是因为我在这方面还是新手,我不明白这里到底发生了什么。有什么帮助吗?

  • TLDR:我有一个pyspark作业,当我在具有16个vcpus的ec2实例中运行它时,它会在10分钟内完成,但如果我使用具有超过20个vcpus的实例,它会冻结(它不会失败,只是永远不会完成)。我已经尝试了我能想到的一切,我只是不知道为什么会发生这种情况。 完整故事: 我有大约200个小型pyspark作业,出于成本和灵活性的考虑,我使用aws batch与spark dockers而不是EMR

  • 我正在将游戏的场景从启动页面切换到游戏,如果我单独玩,游戏场景效果很好,但当我从启动页面切换后玩游戏时,游戏会冻结一段时间。 是什么原因导致我的主游戏在切换场景后冻结了一段时间(一段时间后再次启动),我确信游戏在没有切换场景的情况下运行良好。 程序的控制流程是——从播放器开始,startuppage场景被加载到舞台,如果按下播放按钮,则在主控制器中,场景被切换到我的游戏场景。问题只会在切换场景时出