禁用窗格子项上的所有 MouseEvents
Disable all MouseEvents on the Children of a Pane
我有一个窗格,我在计算期间在其中添加和删除节点。因此我保存了一个布尔值,如果计算是 运行,它被设置为 true。当然我在开始和终止计算时做了一些处理。
我现在想做的是:如果计算开始,则禁用 Pane 子项上的所有 MouseEvents,如果计算终止,则重新启用它们。
到目前为止,我的尝试仅限于完全删除 EventHandlers,但后来我无法再添加它们。
不幸的是我找不到办法做到这一点,所以我希望在这里得到帮助:)
提前致谢
假设您已经将 long-运行 计算实现为 Task
or Service
(如果没有,您应该考虑这样做),您可以按照以下几行做一些事情:
Pane pane ;
// ...
Task<ResultType> computation = ... ;
pane.disableProperty().bind(computation.runningProperty());
new Thread(computation).start();
在一个节点上调用setDisable(true)
会禁用它的所有子节点,所以这会禁用pane
的所有子节点,并在任务不再[=23]时重新启用它们=].
这是一个 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);
}
}
我有一个窗格,我在计算期间在其中添加和删除节点。因此我保存了一个布尔值,如果计算是 运行,它被设置为 true。当然我在开始和终止计算时做了一些处理。
我现在想做的是:如果计算开始,则禁用 Pane 子项上的所有 MouseEvents,如果计算终止,则重新启用它们。
到目前为止,我的尝试仅限于完全删除 EventHandlers,但后来我无法再添加它们。
不幸的是我找不到办法做到这一点,所以我希望在这里得到帮助:)
提前致谢
假设您已经将 long-运行 计算实现为 Task
or Service
(如果没有,您应该考虑这样做),您可以按照以下几行做一些事情:
Pane pane ;
// ...
Task<ResultType> computation = ... ;
pane.disableProperty().bind(computation.runningProperty());
new Thread(computation).start();
在一个节点上调用setDisable(true)
会禁用它的所有子节点,所以这会禁用pane
的所有子节点,并在任务不再[=23]时重新启用它们=].
这是一个 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);
}
}