禁用窗格子项上的所有MouseEvent

时间:2015-08-06 14:31:25

标签: java javafx-8

我有一个Pane,我在计算中添加和删除节点。因此,我保存一个布尔值,如果计算正在运行,则设置为true。当然,我在开始和终止计算时做了一些处理。

我现在要做的是:如果计算开始,则禁用窗格子项上的所有MouseEvent,并在计算终止时重新启用它们。

我的尝试到现在为止仅限于完全删除EventHandlers,但之后我无法再次添加它们。

不幸的是我找不到办法做到这一点,所以我希望在这里寻求帮助:))

提前致谢

1 个答案:

答案 0 :(得分:2)

假设你已经将长时间运行的计算实现为TaskService(如果你没有,你应该考虑这样做),你可以沿着以下几行做一些事情:

Pane pane ;

// ...

Task<ResultType> computation = ... ;

pane.disableProperty().bind(computation.runningProperty());
new Thread(computation).start();

在节点上调用setDisable(true)将禁用其所有子节点,因此这将禁用pane的所有子节点,并在任务不再运行时重新启用它们。

这是一个SSCCE:

import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;

public class ComputationSimulation extends Application {

    @Override
    public void start(Stage primaryStage) {

        // text fields for input:

        TextField xInput = new TextField();
        TextField yInput = new TextField();

        // Service for performing the computation.
        // (For demo here, the computation just computes the sum of 
        // the two input values. Obviously this doesn't take long, so 
        // a random pause is inserted.)

        Service<Integer> service = new Service<Integer>() {

            @Override
            protected Task<Integer> createTask() {

                final int x = readTextField(xInput);
                final int y = readTextField(yInput);

                return new Task<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        // simulate long-running computation...
                        Thread.sleep((int)(Math.random() * 2000) + 1000);

                        // this doesn't really take much time(!):
                        return x + y ;
                    }
                };
            }

        };

        // Label to show result. Just use binding to bind to value of computation:
        Label result = new Label();
        result.textProperty().bind(service.valueProperty().asString());

        // Button starts computation by restarting service:
        Button compute = new Button("Compute");
        compute.setOnAction(e -> service.restart());

        // Pane to hold controls:
        GridPane pane = new GridPane();
        // Disable pane (and consequently all its children) when computation is running:
        pane.disableProperty().bind(service.runningProperty());

        // layout etc:
        pane.setHgap(5);
        pane.setVgap(10);
        pane.addRow(0, new Label("x:"), xInput);
        pane.addRow(1, new Label("y:"), yInput);
        pane.addRow(2, new Label("Total:"), result);
        pane.add(compute, 1, 3);

        ColumnConstraints left = new ColumnConstraints();
        left.setHalignment(HPos.RIGHT);
        left.setHgrow(Priority.NEVER);
        pane.getColumnConstraints().addAll(left, new ColumnConstraints());
        pane.setPadding(new Insets(10));

        Scene scene = new Scene(pane);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    // converts text in text field to an int if possible
    // returns 0 if not valid text, and sets text accordingly
    private int readTextField(TextField text) {
        try {
            return Integer.parseInt(text.getText());
        } catch (NumberFormatException e) {
            text.setText("0");
            return 0 ;
        }
    }

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