Detect Hyperlink hover in WebView and print the link

拈花ヽ惹草 提交于 2019-12-20 04:55:21

问题


I want to add the hovered Hyperlink from a WebView and display it in a corner.

How can i achieve? It should be like Chromes feature:

Example-Chrome-Screenshot

Example WebView Code with many links:

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

回答1:


First thing - your Scene should contain more than one element, not only the ScrollPane. You need a TextField to show hyperlinks' content and these two Controls should be placed on some kind of a Pane. To handle displaying the content when your mouse goes over the hyperlink, you need to get all the nodes, which are of a hyperlink type, and then add proper listeners to them.

Look at the code below, it does what you would like to achieve (it's partially based on the '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);
  }
}



回答2:


My complete example of how to display links from all elements:

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


来源:https://stackoverflow.com/questions/45495758/detect-hyperlink-hover-in-webview-and-print-the-link

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!