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;
}
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(""));
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());
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With