在JavaFX应用程序中更改游标以进行长时间操作

时间:2013-12-13 00:21:29

标签: java javafx

我想在JavaFX应用程序中执行可能很长的操作时将光标更改为Cursor.WAIT。我以为Platform.runLater会帮助我:

this.getStage().getScene().setCursor(Cursor.WAIT);

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        // Do some stuff
        getStage().getScene().setCursor(Cursor.DEFAULT);
    }
});

但是光标不会改变。为什么这不起作用?

1 个答案:

答案 0 :(得分:17)

假设您正在运行JavaFX Application线程的以下代码,则显示等待光标的模式可能是:

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        getStage().getScene().setCursor(Cursor.WAIT);
    }
});

// Do some stuff

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        getStage().getScene().setCursor(Cursor.DEFAULT);
    }
});

或者,如果您已经在JavaFX应用程序线程上,则可以使用Service

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.concurrent.*;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ServiceWithCursorControl extends Application {
    private final Button runButton = new Button("Run");
    private final Label label = new Label();

    private final Service service = new Service() {
        @Override
        protected Task createTask() {
            return new Task<Void>() {
                @Override protected Void call() throws Exception {
                    // do stuff
                    Thread.sleep(5000);
                    return null;
                }
            };
        }
    };

    @Override public void start(Stage stage) {
        VBox layout = createLayout();

        Scene scene = new Scene(layout, 100, 80);
        stage.setScene(scene);

        bindUIandService(stage);

        stage.show();
    }

    private void bindUIandService(Stage stage) {
        label.textProperty()
                .bind(
                        service.stateProperty().asString()
                );

        stage.getScene()
                .getRoot()
                .cursorProperty()
                .bind(
                        Bindings
                            .when(service.runningProperty())
                                .then(Cursor.WAIT)
                                .otherwise(Cursor.DEFAULT)
                );

        runButton
                .disableProperty()
                .bind(
                        service.runningProperty()
                );

        runButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                service.restart();
            }
        });
    }

    private VBox createLayout() {
        VBox layout = new VBox(10);

        layout.getChildren().setAll(runButton, label);
        layout.setPadding(new Insets(10));
        layout.setAlignment(Pos.CENTER);

        return layout;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

从您的描述中不清楚哪种方法最适合您的问题,但希望您可以解决它。