【问题标题】:Detect Hyperlink hover in WebView and print the link检测 WebView 中的超链接悬停并打印链接
【发布时间】:2018-01-11 17:46:14
【问题描述】:

我想从 WebView 添加悬停的超链接并将其显示在角落。

我该如何实现?它应该类似于 Chrome 的功能:

示例-Chrome-屏幕截图

包含许多链接的示例 WebView 代码:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class core extends Application {
    @Override
    public void start(final Stage stage) {
        Scene scene = new Scene(new Group());

        final WebView browser = new WebView();
        final WebEngine webEngine = browser.getEngine();

        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setContent(browser);

        webEngine.load("http://java2s.com");

        scene.setRoot(scrollPane);

        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

【问题讨论】:

    标签: java javafx webview hyperlink javafx-8


    【解决方案1】:

    第一件事 - 你的Scene 应该包含多个元素,而不仅仅是ScrollPane。你需要一个TextField 来显示超链接的内容,这两个Controls 应该放在某种窗格上。 当鼠标经过超链接时,要处理显示内容,您需要获取所有超链接类型的节点,然后为它们添加适当的侦听器。

    看看下面的代码,它做了你想要实现的(它部分基于'JavaFX WebView addHyperlinkListener' article from the 'Inspiration and Expression' blog):

    public class Main extends Application {
    
      @Override
      public void start(final Stage stage) {
        Scene scene = new Scene(new Group());
    
        final WebView browser = new WebView();
        final WebEngine webEngine = browser.getEngine();
    
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setContent(browser);
    
        TextField textField = new TextField();
        textField.setVisible(false);
        textField.setEditable(false);
    
        webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
          if (newValue == Worker.State.SUCCEEDED) {
    
            EventListener mouseOverEventListener = new EventListener() {
              @Override
              public void handleEvent(Event ev) {
                String href = ((Element) ev.getTarget()).getAttribute("href");
                textField.setText(href);
                textField.setVisible(true);
                textField.setPrefWidth(textField.getText().length() * 6); //
                System.out.println(href);
              }
            };
    
            EventListener mouseOutEventListener = new EventListener() {
              @Override
              public void handleEvent(Event ev) {
                textField.setVisible(false);
              }
            };
    
            Document document = webEngine.getDocument();
            NodeList nodeList = document.getElementsByTagName("a");
            for (int i = 0 ; i < nodeList.getLength() ; i++) {
              ((EventTarget) nodeList.item(i)).addEventListener("mouseover",mouseOverEventListener,false);
              ((EventTarget) nodeList.item(i)).addEventListener("mouseout",mouseOutEventListener,false);
            }
          }
        });
    
        String content = "http://java2s.com";
        webEngine.load(content);
    
        AnchorPane anchorPane = new AnchorPane();
        anchorPane.getChildren().add(scrollPane);
        anchorPane.getChildren().add(textField);
        AnchorPane.setBottomAnchor(textField, 0.0);
        AnchorPane.setLeftAnchor(textField, 0.0);
    
        scene.setRoot(anchorPane);
        stage.setScene(scene);
        stage.show();
      }
    
      public static void main(String[] args) {
        launch(args);
      }
    }
    

    【讨论】:

    • 谢谢@notmyf4ulty!这对于文本链接非常有效。但如果我在 java2s.com(广告)有这样的 iframe,我无法显示 targetUrl。
    • @Jinaru 这些广告不是 iframe,而是 Google AdSense 内容。通过在任意位置单击鼠标右键并选择“显示站点源代码”(取决于您使用的网络浏览器)来检查网站的源代码 - 您可以看到它们是带有“google_ad”标签的脚本,甚至是 Chrome 或 Firefox 等流行浏览器都没有'不显示这些广告的链接(我鼓励你自己尝试)。
    • @Jinaru 如果它符合您的需求,请不要忘记接受答案。
    • 我终于做到了。谢谢@notmyf4ulty,您的回答是起点。我将发布我的最终解决方案并接受您的回答。谢谢:)
    【解决方案2】:

    我如何显示所有元素的链接的完整示例:

    import org.w3c.dom.Document;
    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.HTMLIFrameElement;
    import org.w3c.dom.Element;
    import javafx.application.Application;
    import javafx.concurrent.Worker;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.AnchorPane;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.web.WebEngine;
    import javafx.scene.web.WebView;
    import javafx.stage.Stage;
    
    public class getWeblinksInCorner extends Application {
    
        EventListener mouseOverEventListener;
        EventListener mouseOutEventListener;
    
        @Override
        public void start(final Stage stage) {
            final WebView browser = new WebView();
            Label textField = new Label();
    
            final WebEngine webEngine = browser.getEngine();
    
            textField.setVisible(false);
    
            webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
                if (newValue == Worker.State.SUCCEEDED) {
    
                    mouseOverEventListener = new EventListener() {
                        @Override
                        public void handleEvent(Event ev) {
                            String href = getNextHref((Element) ev.getTarget());
                            if (href != null && !href.isEmpty()) {
                                if (href.startsWith("/")) {
                                    href = ((Element) ev.getTarget()).getBaseURI() + href;
                                }
                                textField.setText(href + "   ");
                                textField.setPrefHeight(22);
                                textField.setMaxWidth(650);
                                textField.setStyle("-fx-border-color: #C6C6C7; -fx-background-color: #F2F2F2;");
                                textField.setVisible(true);
                            }
                        }
    
                        private String getNextHref(Element target) {
                            while (target.getAttribute("href") == null) {
                                if (target.toString().contains("HTMLHtmlElement")) {
                                    return "";
                                }
                                target = (Element) target.getParentNode();
                                if (target == null) {
                                    return "";
                                }
                            }
                            return target.getAttribute("href");
                        }
                    };
    
                    mouseOutEventListener = new EventListener() {
    
                        @Override
                        public void handleEvent(Event ev) {
                            textField.setVisible(false);
                        }
                    };
    
                    Document document = webEngine.getDocument();
                    addListener(document.getElementsByTagName("*"));
                }
            });
    
            String content = "http://java2s.com";
            webEngine.load(content);
    
            TextField tf = new TextField();
            tf.textProperty().bind(webEngine.locationProperty());
            BorderPane pane = new BorderPane();
    
            AnchorPane ap = new AnchorPane(browser, textField);
            AnchorPane.setBottomAnchor(browser, 0.0);
            AnchorPane.setLeftAnchor(browser, 0.0);
            AnchorPane.setTopAnchor(browser, 0.0);
            AnchorPane.setRightAnchor(browser, 0.0);
            AnchorPane.setBottomAnchor(textField, 0.0);
            AnchorPane.setLeftAnchor(textField, 0.0);
            pane.setCenter(ap);
            pane.setTop(tf);
    
            Scene scene = new Scene(pane);
            stage.setScene(scene);
            stage.show();
        }
    
        private void addListener(NodeList nodeList) {
            for (int i = 0; i < nodeList.getLength(); i++) {
                try {
                    HTMLIFrameElement iFrame = ((HTMLIFrameElement) nodeList.item(i));
                    addListener(iFrame.getContentDocument().getElementsByTagName("*"));
                } catch (Exception e) {
                    Element el = (Element) nodeList.item(i);
                    while (!el.toString().contains("HTMLHtmlElement")) {
                        el = (Element) el.getParentNode();
                        ((EventTarget) el).removeEventListener("mouseover", mouseOverEventListener, false);
                        ((EventTarget) el).removeEventListener("mouseout", mouseOutEventListener, false);
                    }
                    ((EventTarget) nodeList.item(i)).addEventListener("mouseover", mouseOverEventListener, false);
                    ((EventTarget) nodeList.item(i)).addEventListener("mouseout", mouseOutEventListener, false);
                }
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-09
      • 1970-01-01
      • 2017-07-08
      • 2021-10-24
      • 1970-01-01
      • 2014-06-09
      • 1970-01-01
      • 2020-09-13
      • 1970-01-01
      相关资源
      最近更新 更多