JavaFX在WebView中停止打开URL - 而不是在浏览器中打开 [英] JavaFX stop opening URL in WebView - open in browser instead

查看:104
本文介绍了JavaFX在WebView中停止打开URL - 而不是在浏览器中打开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的嵌入式WebView浏览器需要对特定URL进行特殊处理,以在本机默认浏览器而不是WebView中打开它们。实际的浏览部分工作正常但我需要阻止WebView显示该页面。我可以想到几种方法,但没有一种方法可行。这是我的代码:

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 works fine but I need to stop the WebView from displaying that page as well. I can think of several ways to do it but none of them work. Here is my code:

this.wv.getEngine().locationProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue)
    {
        Desktop d = Desktop.getDesktop();
        try
        {
            URI address = new URI(observable.getValue());
            if ((address.getQuery() + "").indexOf("_openmodal=true") > -1)
            {
                // wv.getEngine().load(oldValue); // 1
                // wv.getEngine().getLoadWorker().cancel(); // 2
                // wv.getEngine().executeScript("history.back()"); // 3
                d.browse(address);
            }
        }
        catch (IOException | URISyntaxException e)
        {
            displayError(e);
        }
    }
});

关于三种情况中每种情况会发生什么的更多信息

A bit more info about what happens in each of three cases

wv.getEngine().load(oldValue);

这会杀死JVM。有趣的是,页面在本机浏览器中打开正常。

This kills the JVM. Funnily enough, the page opens fine in the native browser.

# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000005b8fef38, pid=7440, tid=8000
#
# JRE version: 7.0_09-b05
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.5-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [jfxwebkit.dll+0x2fef38]  Java_com_sun_webpane_platform_BackForwardList_bflItemGetIcon+0x184f58
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\Greg Balaga\eclipse\Companyapp\hs_err_pid7440.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.



2。取消工人



2. Cancelling the worker

wv.getEngine().getLoadWorker().cancel();

什么都不做,页面加载WebView和本机浏览器。

Does nothing, the page loads in both the WebView and native browser.

wv.getEngine().executeScript("history.back()");

与上述相同,无效。

我也尝试过而不是寻找 locationProperty WebEngine ,收听工人 stateProperty 的变形并触发相同的开启代码 newState == State.SCHEDULED 。与先前方法的结果没有区别(除了实际上不能使用#1)。

I have also tried to instead of looking the locationProperty of WebEngine, listen on chenges for stateProperty of the Worker and fire the same opening code if newState == State.SCHEDULED. There was no difference in result from previous method (apart from not actually being able to use #1).

我现在使用的代码仍会崩溃JVM:

The code I'm using now still crashes the JVM:

this.wv.getEngine().locationProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, final String oldValue, String newValue)
    {
        Desktop d = Desktop.getDesktop();
        try
        {
            URI address = new URI(newValue);
            if ((address.getQuery() + "").indexOf("_openmodal=true") > -1)
            {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run()
                    {
                        wv.getEngine().load(oldValue);
                    }
                });
                d.browse(address);
            }
        }
        catch (IOException | URISyntaxException e)
        {
            displayError(e);
        }
    }
});






解决方法



好的,我设法通过拆除webview并重建它来使其工作。


Workaround

Ok I managed to make it work by tearing down the webview and rebuilding it.

this.wv.getEngine().locationProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, final String oldValue, String newValue)
    {
        Desktop d = Desktop.getDesktop();
        try
        {
            URI address = new URI(newValue);
            if ((address.getQuery() + "").indexOf("_openmodal=true") > -1)
            {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run()
                    {
                        grid_layout.getChildren().remove(wv);
                        wv = new WebView();
                        grid_layout.add(wv, 0, 1);
                        wv.getEngine().load(oldValue);
                    }
                });
                d.browse(address);
            }
        }
        catch (IOException | URISyntaxException e)
        {
            displayError(e);
        }
    }
});


推荐答案

还有另一种处理方法。

您可以向DOM元素添加一个事件监听器并以此方式拦截它。

You can add an event listener to the DOM elements and intercept it that way.

示例:

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);
            }

其中document是DOM文档对象。
确保在文档加载完成后完成此操作。

Where document is the DOM document object. Make sure this is done after the document has finished loading.

这篇关于JavaFX在WebView中停止打开URL - 而不是在浏览器中打开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆