User interface 如何在任务完成后在javafx中显示和隐藏标签

User interface 如何在任务完成后在javafx中显示和隐藏标签,user-interface,javafx,label,User Interface,Javafx,Label,我想在按下按钮后显示标签,但在按钮所做的操作完成后,我想隐藏标签 这就是我一直试图做的 final Label loadingLabel = new Label(); loadingLabel.setText("Loading..."); loadingLabel.setFont(Font.font("Arial", 16)); BorderPane root = new BorderPane(); root.setRight(label); r

我想在按下按钮后显示标签,但在按钮所做的操作完成后,我想隐藏标签

这就是我一直试图做的

    final Label loadingLabel = new Label();
    loadingLabel.setText("Loading...");
    loadingLabel.setFont(Font.font("Arial", 16));

    BorderPane root = new BorderPane();
    root.setRight(label);
    root.setLeft(button);
    root.setCenter(loadingLabel);
    loadingLabel.setVisible(false);

final Button printButton = new Button("Print part");
    printButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent e) {
            loadingLabel.setVisible(true);
            //here are some computations
            loadingLabel.setVisible(false);
        }
    }
最终标签加载标签=新标签();
loadingLabel.setText(“加载…”);
加载label.setFont(Font.Font(“Arial”,16));
BorderPane根=新的BorderPane();
root.setRight(标签);
root.setLeft(按钮);
root.setCenter(加载标签);
loadingLabel.setVisible(假);
最终按钮printButton=新按钮(“打印部件”);
setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent e){
loadingLabel.setVisible(true);
//这里有一些计算
loadingLabel.setVisible(假);
}
}

代码根本不会显示在标签上。

下面是一个简单的示例,说明如何使用及其更新标签的可见性

使用服务代替任务,因为我们需要定义一个可重用的工作对象

import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class SimpleTaskExample extends Application {

    Service service = new ProcessService();

    @Override
    public void start(Stage primaryStage) throws Exception {
        Button button = new Button("Press Me to start new Thread");

        Label taskLabel = new Label("Task Running..");
        taskLabel.setVisible(false);
        Label finishLabel = new Label("Task Completed.");
        finishLabel.setVisible(false);

        VBox box = new VBox(20, taskLabel, button, finishLabel);
        box.setAlignment(Pos.CENTER);
        primaryStage.setScene(new Scene(box, 200, 200));
        primaryStage.show();

        button.setOnAction(event -> {

            // show the label
            taskLabel.setVisible(true);
            // hide finish label
            finishLabel.setVisible(false);
            // start background computation
            if(!service.isRunning())
                service.start();
        });

        // If task completed successfully, hide the label
        service.setOnSucceeded(e -> {
            taskLabel.setVisible(false);
            finishLabel.setVisible(true);
            //reset service
            service.reset();
        });
    }

    class ProcessService extends Service<Void> {

        @Override
        protected Task<Void> createTask() {
            return new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    // Computations takes 3 seconds
                    // Calling Thread.sleep instead of random computation
                    Thread.sleep(3000);
                    return null;
                }
            };
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
导入javafx.application.application;
导入javafx.concurrent.Service;
导入javafx.concurrent.Task;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类SimpleTaskExample扩展了应用程序{
服务=新的ProcessService();
@凌驾
public void start(Stage primaryStage)引发异常{
按钮按钮=新按钮(“按我开始新线程”);
标签taskLabel=新标签(“正在运行的任务”);
taskLabel.setVisible(false);
Label finishLabel=新标签(“任务已完成”);
finishLabel.setVisible(假);
VBox框=新的VBox(20,任务标签,按钮,完成标签);
框。设置对齐(位置中心);
初级舞台。背景场景(新场景(框,200200));
primaryStage.show();
按钮。设置操作(事件->{
//显示标签
taskLabel.setVisible(true);
//隐藏完成标签
finishLabel.setVisible(假);
//开始背景计算
如果(!service.isRunning())
service.start();
});
//如果任务成功完成,则隐藏标签
service.setonSucceed(e->{
taskLabel.setVisible(false);
finishLabel.setVisible(true);
//重置服务
service.reset();
});
}
类ProcessService扩展服务{
@凌驾
受保护的任务createTask(){
返回新任务(){
@凌驾
受保护的Void调用()引发异常{
//计算需要3秒钟
//调用Thread.sleep而不是随机计算
睡眠(3000);
返回null;
}
};
}
}
公共静态void main(字符串[]args){
发射(args);
}
}

您还可以在
runningProperty()上使用侦听器
,如果您想隐藏标签,而不管任务是否成功。

您的计算是在后台线程上完成的吗?不,它们是在同一线程上完成的如果它们是长时间工作的计算,那么它们将阻止
JavaFX应用程序线程
冻结UI,从而导致糟糕的用户体验。everything只花了不到10秒的时间,是不是冻结了UI?我该怎么办?我没有太多的线程工作经验,代码是按照你的模型制作的,但仍然不起作用。到底什么不起作用?你确定任务是在
Worker.State为successed
的情况下完成的吗?如果可能,请询问其他任务问题是标签仍然没有出现,否则程序运行与以前完全相同。我如何将Worker.State设置为successed?在调用中,我只在末尾返回null除了
返回null
,任务的调用方法中还有什么其他内容?可能是task未成功完成。啊,我明白了。因为任务类定义了一个不能重用的一次性对象。您需要改用
服务
。请检查更新的答案。