JavaFX stop opening URL in WebView - open in browser instead
I finally found a working solution that worked for me:
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.scene.web.WebView;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.html.HTMLAnchorElement;
import java.awt.*;
import java.net.URI;
public class HyperLinkRedirectListener implements ChangeListener<Worker.State>, EventListener
{
private static final String CLICK_EVENT = "click";
private static final String ANCHOR_TAG = "a";
private final WebView webView;
public HyperLinkRedirectListener(WebView webView)
{
this.webView = webView;
}
@Override
public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue)
{
if (Worker.State.SUCCEEDED.equals(newValue))
{
Document document = webView.getEngine().getDocument();
NodeList anchors = document.getElementsByTagName(ANCHOR_TAG);
for (int i = 0; i < anchors.getLength(); i++)
{
Node node = anchors.item(i);
EventTarget eventTarget = (EventTarget) node;
eventTarget.addEventListener(CLICK_EVENT, this, false);
}
}
}
@Override
public void handleEvent(Event event)
{
HTMLAnchorElement anchorElement = (HTMLAnchorElement) event.getCurrentTarget();
String href = anchorElement.getHref();
if (Desktop.isDesktopSupported())
{
openLinkInSystemBrowser(href);
} else
{
// LOGGER.warn("OS does not support desktop operations like browsing. Cannot open link '{}'.", href);
}
event.preventDefault();
}
private void openLinkInSystemBrowser(String url)
{
// LOGGER.debug("Opening link '{}' in default system browser.", url);
try
{
URI uri = new URI(url);
Desktop.getDesktop().browse(uri);
} catch (Throwable e)
{
// LOGGER.error("Error on opening link '{}' in system browser.", url);
}
}
}
Usage:
webView.getEngine().getLoadWorker().stateProperty().addListener(new HyperLinkRedirectListener(webView));
There is another method for handling this.
You can add an event listener to the DOM elements and intercept it that way.
Example:
NodeList nodeList = document.getElementsByTagName("a");
for (int i = 0; i < nodeList.getLength(); i++)
{
Node node= nodeList.item(i);
EventTarget eventTarget = (EventTarget) node;
eventTarget.addEventListener("click", new EventListener()
{
@Override
public void handleEvent(Event evt)
{
EventTarget target = evt.getCurrentTarget();
HTMLAnchorElement anchorElement = (HTMLAnchorElement) target;
String href = anchorElement.getHref();
//handle opening URL outside JavaFX WebView
System.out.println(href);
evt.preventDefault();
}
}, false);
}
Where document is the DOM document object. Make sure this is done after the document has finished loading.