I'm using JavaFX/JXBrowser to show an alert/dialog when the web page loaded into the Browser calls on Window.alert or window.confirm. However, I can't figure out how to return the result of the confirmation dialog (true/false) to JS. Since alert.showAndWait() is a blocking function, JS should wait for this result. However, showAndWait is also called in a Platform.runLater runnable, so I can't return the result. Short of writing JS functions to do the true/false code and calling those based on the result of showAndWait, is there any other option?
browser.setDialogHandler(new DialogHandler() {
@Override
public CloseStatus onConfirmation(DialogParams params) {
Platform.runLater(new Runnable() {
@Override
public void run() {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Yes/No");
alert.setHeaderText(null);
alert.setContentText("Yes/No");
Optional<ButtonType> result = alert.showAndWait();
if(result.isPresent())
{
if(result.get()==ButtonType.YES)
{
//Send true to calling JS function
}else
{
//Send false to calling JS function
}
}else
{
System.out.println("No result!");
}
}
});
return null; //because I need to return something and I can't figure out how to get values from the runnable
}
...
}
You can use the following approach:
@Override
public CloseStatus onConfirmation(DialogParams params) {
final AtomicReference<CloseStatus> status = new AtomicReference<CloseStatus>();
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
@Override
public void run() {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Yes/No");
alert.setHeaderText(null);
alert.setContentText("Yes/No");
Optional<ButtonType> result = alert.showAndWait();
if (result.isPresent()) {
if (result.get() == ButtonType.YES) {
status.set(CloseStatus.OK);
} else {
status.set(CloseStatus.CANCEL);
}
} else {
System.out.println("No result!");
}
}
});
try {
latch.await();
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
return status.get();
}