将程序输出附加到JavaFX TextBox

时间:2016-03-25 13:55:19

标签: java multithreading javafx concurrency runtime

我有一个批处理文件,应该从我的JavaFX应用程序启动。

我尝试了不同的实现:

将程序的输出附加到文件中,然后在该过程完成后,读取该文件,并将内容附加到我的TextBox。

出于多种原因这是错误的,主要是因为GUI挂起,直到程序结束。

所以我研究了使用线程,但是在线程中使用Initial Value时,会发生同样的事情。 我尝试在进程运行时这样做,将输出的内容添加到我的textBox。只有在程序结束后才会添加它,即使我是在一个单独的线程中执行此操作。

我也试图使用while(process.isAlive())。 有了这个,内容会定期更新,但一次仍然在大块数据中,并且还会使GUI挂起。

然后我发现JavaFX不是线程安全的,并且有一个库:

Platform.runLater(new Runnable() ...

这里有一个例子: https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm

但是,我仍然不确定我是否正在接近我正在寻找的东西......

基本上,我需要这样的东西,但这会使GUI不挂起:

javafx.concurrent.Task

1 个答案:

答案 0 :(得分:-1)

解决方案只是构建一个任务,如链接中所示,并将主帖中的代码放入其中。

感谢James_D,你的伎俩做到了。

这是最终结果:

Task task = new Task<Void>()
        {
            @Override
            public Void call()
            {
                try {
                    Process p = Runtime.getRuntime().exec(executeString);                
                    InputStream is = p.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader br = new BufferedReader(isr);

                    while(p.isAlive())
                    {
                        String line;
                        if ( (line = br.readLine()) != null)
                            logArea.appendText(line + "\n");
                    }
                } catch (IOException e)
                {
                    e.printStackTrace();
                }
                return null;
            }
        }; 
        new Thread(task).start();

编辑: 在阅读了更多的文件......

http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm

http://docs.oracle.com/javafx/2/api/javafx/concurrent/Task.html

Platform.runLater and Task in JavaFX

代码已更新为:

                while(p.isAlive())
                {
                    String line;
                    if ((line = br.readLine()) != null)
                    {
                        Platform.runLater(new Runnable() 
                        {
                            @Override
                            public void run()
                            {
                                logArea.appendText(line + "\n");
                            }
                        });
                    }
                }