示例解决方案
也许您想要做的是显示提示对话框并使用showAndWait等待从提示对话框中获取响应,然后再继续。类似于JavaFX2:我可以暂停后台任务/服务吗?
可能您的情况比后台任务服务简单一些(除非涉及长时间运行的任务),您可以在JavaFX应用程序线程上执行所有操作。我创建了一个简单的示例解决方案,它只在JavaFX应用程序线程上运行所有操作。
以下是示例程序的输出:
![prompteddata](https://istack.dev59.com/svLso.webp)
![prompt](https://istack.dev59.com/PdnpD.webp)
每次遇到缺失数据时,都会显示提示对话框,并等待用户输入以填写缺失数据(在上面的屏幕截图中,用户提供的响应以绿色突出显示)。
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.*;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class MissingDataDemo extends Application {
private static final String[] SAMPLE_TEXT =
"Lorem ipsum MISSING dolor sit amet MISSING consectetur adipisicing elit sed do eiusmod tempor incididunt MISSING ut labore et dolore magna aliqua"
.split(" ");
@Override public void start(Stage primaryStage) {
VBox textContainer = new VBox(10);
textContainer.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
primaryStage.setScene(new Scene(textContainer, 300, 600));
primaryStage.show();
TextLoader textLoader = new TextLoader(SAMPLE_TEXT, textContainer);
textLoader.loadText();
}
public static void main(String[] args) { launch(args); }
}
class TextLoader {
private final String[] lines;
private final Pane container;
TextLoader(final String[] lines, final Pane container) {
this.lines = lines;
this.container = container;
}
public void loadText() {
for (String nextText: lines) {
final Label nextLabel = new Label();
if ("MISSING".equals(nextText)) {
nextLabel.setStyle("-fx-background-color: palegreen;");
MissingTextPrompt prompt = new MissingTextPrompt(
container.getScene().getWindow()
);
nextText = prompt.getResult();
}
nextLabel.setText(nextText);
container.getChildren().add(nextLabel);
}
}
class MissingTextPrompt {
private final String result;
MissingTextPrompt(Window owner) {
final Stage dialog = new Stage();
dialog.setTitle("Enter Missing Text");
dialog.initOwner(owner);
dialog.initStyle(StageStyle.UTILITY);
dialog.initModality(Modality.WINDOW_MODAL);
dialog.setX(owner.getX() + owner.getWidth());
dialog.setY(owner.getY());
final TextField textField = new TextField();
final Button submitButton = new Button("Submit");
submitButton.setDefaultButton(true);
submitButton.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent t) {
dialog.close();
}
});
textField.setMinHeight(TextField.USE_PREF_SIZE);
final VBox layout = new VBox(10);
layout.setAlignment(Pos.CENTER_RIGHT);
layout.setStyle("-fx-background-color: azure; -fx-padding: 10;");
layout.getChildren().setAll(
textField,
submitButton
);
dialog.setScene(new Scene(layout));
dialog.showAndWait();
result = textField.getText();
}
private String getResult() {
return result;
}
}
}
现有提示对话框库
ControlsFX 库中有一个预先编写的提示对话框,可以为您处理提示对话框的显示。
澄清事件处理和繁忙等待
您想要:
一个函数,等待用户在我文本字段中输入文本并按“enter”键。
按定义,这就是EventHandler的作用。
当发生此处理程序注册的特定事件时会触发 EventHandler。
当事件发生时,您的事件处理程序将被触发,并且您可以在事件处理程序中执行任何操作 - 您不需要,也不应该使用繁忙等待循环来等待事件。
创建TextField操作事件处理程序
与其像您在问题中所做的那样将事件处理程序放在窗口上,最好使用textField.setOnAction在您的文本字段上使用特定的操作事件处理程序:
textField.setOnAction(
new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
}
);
如果您将文本字段放置在具有默认按钮集的对话框中,则无需为文本字段设置事件处理程序,因为对话框的默认按钮将适当地拾取并处理回车键事件。