执行流程时更新TextArea

Bla*_*ACE 0 concurrency user-interface javafx updates fxml

我发现当我单击“无响应”之类的“开始”按钮时,我的GUI在3-4秒后开始冻结。当我继续单击该应用程序时,它被迫关闭。
现在我想防止这种情况,但是我不知道如何。据我所知,JavaFX在单线程中运行,因此,要在执行方法时更新我的​​TextArea,我需要在另一个线程中运行这些方法。
我希望有一个人可以帮助我。

我的项目看起来如何?

我有一个FXML,一个控制器,一个处理程序,一个Transformer,还有一个Writer和Reader类(在Handler类中使用)。
当我单击绑定到Controller中的方法的按钮时,将创建Handler的实例,该实例调用Reader读取文本文件,并将其转换为字符串列表(逐行)。
另外,生产线正在被操纵。此后,使用Writer创建一个新文件,并将新的操纵行写入该文件。
还允许用户引用多个文件。
我想要的是,每当读者开始读取“正在读取文件...”之类的文件时,文本区域都会显示。
然后在Transformer生效时附加“正在操纵文件...”,然后
将新行写入新文件时,“正在写入文件...”。

这是一些代码。
控制器:

public class FXMLDocumentController implements Initializable {

@FXML
private TextArea console;

@FXML
private void handleButtonAction(ActionEvent event) {
    System.out.println("You clicked me!");
    Handler hand = new Handler();
    hand.handle(files);
}

@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO
}    

}
Run Code Online (Sandbox Code Playgroud)

处理程序:

public class Handler {

public void handle(List<String> files) {
    for (String s : files) {
        List<String> ls = Reader.readFile(s);
        Writer.writeFile(Transformer.transform(ls));
    }
}
Run Code Online (Sandbox Code Playgroud)

每当读取,操作或写入文件时,应如何更改代码以更新TextArea?

信息:我知道Handler将无法编译,因为我删除了包含文件路径字符串的列表“文件”的初始化。

如果我遗漏了相关信息,请随时提问。
我提前谢谢你!

Jam*_*s_D 5

您应该handle()在后台线程中执行该方法:

@FXML
private void handleButtonAction(ActionEvent event) {
    System.out.println("You clicked me!");

    Thread thread = new Thread(() -> {
        Handler hand = new Handler();
        hand.handle(files);
    });

    // this line means the background thread will not prevent application exit:
    thread.setDaemon(true);

    thread.start();
}
Run Code Online (Sandbox Code Playgroud)

如果要用当前状态更新文本区域,则需要使用来安排将其安排回FX Application Thread上Platform.runLater()。可能最干净的方法不是Platform.runLater()Handler类中,而是在其中定义Handler用于“使用”状态消息的字段:

public class Handler {

    private final Consumer<String> statusMessageProcessor ;

    public Handler(Consumer<String> statusMessageProcessor) {
        this.statusMessageProcessor = statusMessageProcessor ;
    }

    // default processor does nothing:
    public Handler() {
        this(s -> {});
    }

    public void handle(List<String> files) {
        for (String s : files) {

            // similarly for other status updates:
            statusMessageProcessor.accept("The file "+s+" is being read");

            List<String> ls = Reader.readFile(s);
            Writer.writeFile(Transformer.transform(ls));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后

Handler hand = new Handler() ;
Run Code Online (Sandbox Code Playgroud)

可以变成

Handler hand = new Handler(message -> 
    Platform.runLater(() -> console.appendText(message + "\n")));
Run Code Online (Sandbox Code Playgroud)

在按钮处理程序方法中。