The embedded WebView browser I am using needs special handling for particular URLs, to open them in the native default browser instead of WebView. The actual browsing part w
I found another solution:
I implemented it so the secondary WebEngine is initialized lazy. It may also be initialized in the constructor. Both has pros and contras.
Note: This only triggers for Links which open as a popup. This usually is the case when an a-element has a target-attribute that is not "_self" or with JS: window.open(...)
.
Here is the Magic ...
Register it like this:
engine.setCreatePopupHandler(new BrowserPopupHandler());
The core class:
public static class BrowserPopupHandler implements Callback
{
private WebEngine popupHandlerEngine;
public WebEngine call(PopupFeatures popupFeatures)
{
// by returning null here the action would be canceled
// by returning a different WebEngine (than the main one where we register our listener) the load-call will go to that one
// we return a different WebEngine here and register a location change listener on it (see blow)
return getPopupHandler();
}
private WebEngine getPopupHandler()
{
if (popupHandlerEngine == null) // lazy init - so we only initialize it when needed ...
{
synchronized (this) // double checked synchronization
{
if (popupHandlerEngine == null)
{
popupHandlerEngine = initEngine();
}
}
}
return popupHandlerEngine;
}
private WebEngine initEngine()
{
final WebEngine popupHandlerEngine = new WebEngine();
// this change listener will trigger when our secondary popupHandlerEngine starts to load the url ...
popupHandlerEngine.locationProperty().addListener(new ChangeListener()
{
public void changed(ObservableValue extends String> observable, String oldValue, String location)
{
if (!location.isEmpty())
{
Platform.runLater(new Runnable()
{
public void run()
{
popupHandlerEngine.loadContent(""); // stop loading and unload the url
// -> does this internally: popupHandlerEngine.getLoadWorker().cancelAndReset();
}
});
try
{
// Open URL in Browser:
Desktop desktop = Desktop.getDesktop();
if (desktop.isSupported(Desktop.Action.BROWSE))
{
URI uri = new URI(location);
desktop.browse(uri);
}
else
{
System.out.println("Could not load URL: " + location);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
});
return popupHandlerEngine;
}
}