【问题标题】:JavaFX - Freezing when attempting to use BufferedReader - Unclosed?JavaFX - 尝试使用 BufferedReader 时冻结 - 未关闭?
【发布时间】:2015-04-13 17:16:16
【问题描述】:

我已经尝试了好几个小时试图弄清楚这一点,但它已经开始让我烦恼了。

我有一个简单的 JavaFX 应用程序,然后当一个按钮被点击时,它

执行Process p = pb.start()

命令运行,并且可以在终端窗口中看到,但 GUI 完全冻结。

//A lot of unused imports I know...

public class GUI extends Application {

    GridPane grid;
    Scene scene; 
    Button btn1;
    Button btn2;
    TextArea text;
    Label lbl1;
    Label lbl2;

    @Override

    public void start(Stage primaryStage) throws IOException {

        primaryStage.setTitle("Flashing - ROMMING - Recovery - Rooting");
        grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setGridLinesVisible(true);
        scene = new Scene(grid,1000, 1000);
        text = new TextArea();
        text.setText("Commands will be Shown Here");

        btn1 = new Button("ADB List Devices");
        btn2 = new Button("ADB Reboot");
        btn1.setMinSize(50, 25);
        btn2.setMinSize(50, 25);
        btn1.addEventHandler(ActionEvent.ACTION, lsDevice);

        grid.add(btn1, 0, 1);
        grid.add(btn2, 0, 2);
        grid.add(text, 0, 3);

        primaryStage.setScene(scene);
        primaryStage.show();

    }
    //Logger

    //Event Handlers
    EventHandler<ActionEvent> lsDevice = new EventHandler<ActionEvent>() {
        public void handle(ActionEvent e) {
            System.out.println("Handling event " + e.getEventType());
            ProcessBuilder pb = new ProcessBuilder().command("cmd.exe");

            File log = new File("log");
            String line = null;
            try {
                 Process p = pb.start();
                 BufferedReader stdInput = new BufferedReader(new
                         InputStreamReader(p.getInputStream()));
                    // read the output from the command
                    while((line=stdInput.readLine())!=null){
                           System.out.println(line);
                    }
                }
                catch (Exception e1) {
                    e1.printStackTrace();
            }
            e.consume();
        } 
    };
}

任何帮助将不胜感激。

顺便说一句,我的场景中有一个TextArea,我想在运行命令时更新它。

例如,如果单击ver 按钮,则在TextArea 中我希望它更新。我试过text.appendText(string)

有什么帮助吗?

谢谢!

【问题讨论】:

  • 您正在 FX 应用程序线程中运行循环,该循环在 readLine 上阻塞。您需要在后台线程中运行它。

标签: java javafx


【解决方案1】:

问题

问题是因为在 JavaFX 应用程序线程而不是后台线程中处理长时间运行的任务。

解决方案

将处理工作移到一个新的Task中,点击Button启动Task。

Task<String> task = new Task<String>() {
     @Override 
     protected Integer call() throws Exception {
          try {
             Process p = pb.start();
             BufferedReader stdInput = new BufferedReader(new
             InputStreamReader(p.getInputStream()));
             // read the output from the command
             while((line=stdInput.readLine())!=null){
                  System.out.println(line);
                  // To update the textarea
                  updateMessage(line);
             }
          }
          catch (Exception e1) {
             e1.printStackTrace();
          }
     }
};

处理程序内部:

Thread th = new Thread(task);
th.setDaemon(true);
th.start();

textarea,可以绑定成

textarea.textProperty().bind().(Bindings.concat(textArea.getText()).concat(task.messageProperty()));

欲了解更多信息,请转至Concurrency in JavaFX

注意 即时编写代码。可能包含拼写错误。

【讨论】:

  • 谢谢!我在线程等方面做得不多。我认为自己是一个“菜鸟”,因为我通过尝试、做一些研究然后问我什么时候被卡住来学习。你能解释一下Task&lt;String&gt; task = new Task&lt;String&gt;() {这行吗?我知道它正在创建一个新任务,但我不明白为什么&lt;String&gt;在那里。您是否有机会将我链接到引用 &lt;&gt; 的 Javadoc,谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多