问题描述
我正在开发 JavaFX 应用程序,在我的场景中是显示在 JavaFX 中创建的密码提示,它使用两个选项 OK
和 Cancel
获取密码.我已返回用户输入的密码.
I am working on JavaFX application, in my scenario is to show a password prompt created in JavaFX which takes password with two option OK
and Cancel
. I have returned the password entered by user.
我显示密码对话框的类是 -
My class of showing password dialog is -
public static String showPasswordDialog(String title, String message, Stage parentStage, double w, double h) {
try {
Stage stage = new Stage();
PasswordDialogController controller = (PasswordDialogController) Utility.replaceScene("Password.fxml", stage);
passwordDialogController.init(stage, message, "/images/password.png");
if (parentStage != null) {
stage.initOwner(parentStage);
}
stage.initModality(Modality.WINDOW_MODAL);
stage.initStyle(StageStyle.UTILITY);
stage.setResizable(false);
stage.setWidth(w);
stage.setHeight(h);
stage.showAndWait();
return controller.getPassword();
} catch (Exception ex) {
return null;
}
我的代码在下面显示密码提示,实际上这个提示会显示在其他UI上,所以我需要将它包含在Platform.runlater()
中,否则它会抛出Not在 FX 应用程序线程上
.我需要显示此密码提示,直到我得到正确的密码提示.如果我在 runlater 中包含显示密码,我如何获取密码的值.
My code where to show password prompt is below, actually this prompt will be shown over other UI, so I need to inclose this inside Platform.runlater()
, otherwise it throws Not on FX application thread
. I need this password prompt to be shown until I get correct one. How can I get value of password if I inclosed showing password inside runlater.
还有其他更好的方法吗?
Is there any other better way?
final String sPassword = null;
do {
Platform.runLater(new Runnable() {
@Override
public void run() {
sPassword = JavaFXDialog.showPasswordDialog(sTaskName + "Password", "Enter the password:", parentStage, 400.0, 160.0);
}
});
if (sPassword == null) {
System.out.println("Entering password cancelled.");
throw new Exception("Cancel");
}
} while (sPassword.equalsIgnoreCase(""));
推荐答案
我建议将代码包装在 FutureTask
对象中.FutureTask
是一种有用的构造(除其他外),用于在一个线程(通常是工作线程,在您的情况下是事件队列)上执行部分代码并在另一个线程上安全地检索它.FutureTask#get
将阻塞,直到 FutureTask#run
被调用,因此您的密码提示可能如下所示:
I'd recommend wrapping the code within a FutureTask
object. FutureTask
is a construct useful (among other things) for executing a portion of code on one thread (usually a worker, in your case the event queue) and safely retrieving it on another. FutureTask#get
will block until FutureTask#run
has been invoked, therefore your password prompt could look like this:
final FutureTask query = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
return queryPassword();
}
});
Platform.runLater(query);
System.out.println(query.get());
由于FutureTask
实现了Runnable,您可以将其直接传递给Platform#runLater(...)
.queryPassword()
将在事件队列中被调用,随后的 get 调用将被阻塞,直到该方法完成.当然,您会希望循环调用此代码,直到密码实际匹配为止.
As FutureTask
implements Runnable, you can pass it directly to Platform#runLater(...)
. queryPassword()
will be inokved on the event queue, and the subsequent call to get block until that method completes. Of course, you will want to invoke this code in a loop until the password actually matches.
这篇关于从 javafx 平台 runlater 返回结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!