JavaFX WebView - 获取“复制链接到剪贴板”功能

问题描述 投票:0回答:1

我想在 WebView 中获取网站链接的 URL。默认情况下,您可以使用默认的上下文菜单并右键单击链接并选择“将链接复制到剪贴板”。但是我有一个自定义的 ContextMenu,所以我不能使用它。有没有办法访问该方法或获取右键单击的链接的 URL 的其他方法? 到目前为止,我有一个引用 MenuItem 而不是链接的 ActionListener。

   public void createContextMenu() {
      ContextMenu contextMenu = new ContextMenu();

      MenuItem menuItem_download = new MenuItem("Download");
      contextMenu.getItems().add(menuItem_download);

      menuItem_download.setOnAction(e -> fileDownloadContextMenu(e));

      webView.setOnMousePressed(e -> {
         if (e.getButton() == MouseButton.SECONDARY) {
            contextMenu.show(webView, e.getScreenX(), e.getScreenY());
         } else{
            contextMenu.hide();
         }
      });
   }
   public void fileDownloadContextMenu(Event e) {

      System.out.println(e.getSource());
      
      // Code for downloading
   }

谢谢。

编辑: 我为连接的字符串尝试了这个:

   private final String getHrefJs = "var elt = document.elementFromPoint(%f, %f);\n" +
            "var href = \"\";\n" +
            "if (elt.tagName.toLowerCase() == \"a\"){\n" +
            "href = elt.getAttribute(\"href\");}\n" +
            "href\n";
url javafx webview contextmenu
1个回答
2
投票

如果右键单击

A
标签,您可以使用一些 Javascript 来检索链接。然后只需使用一些标准的 JavaFX 将其复制到剪贴板。

Javascript 策略只是在鼠标坐标处查找 HTML 元素,检查其标记名,如果它是锚点,则从中检索

href
属性。

可能有更简单的方法来实现这一点,但这似乎有效。

import javafx.application.Application;
import javafx.geometry.Side;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

import java.net.URI;
import java.net.URISyntaxException;

public class HelloApplication extends Application {

    private String link;
    private WebView webView;
    private WebEngine engine;
    private ContextMenu contextMenu;

    private final String getHrefJs = """
                var elt = document.elementFromPoint(%f, %f);
                var href = "";
                if (elt.tagName.toLowerCase() == "a") {
                    href = elt.getAttribute("href");
                }
                href
        """;

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

    @Override
    public void start(Stage stage) {
        webView = new WebView();
        webView.setContextMenuEnabled(false);
        engine = webView.getEngine();
        engine.load("https://repo.maven.apache.org/maven2/");

        MenuItem copyLink = new MenuItem("Copy link address");
        Label linkLabel = new Label();
        copyLink.setOnAction(e -> {
            linkLabel.setText(link);
            Clipboard clipboard = Clipboard.getSystemClipboard();
            ClipboardContent content = new ClipboardContent();
            content.putString(link);
            clipboard.setContent(content);
        });

        contextMenu = new ContextMenu(copyLink);

        webView.setOnContextMenuRequested(e -> {
            try {
                showMenuIfNeeded(e.getX(), e.getY());
            } catch (URISyntaxException ex) {
                throw new RuntimeException(ex);
            }
        });

        BorderPane root = new BorderPane(webView);
        root.setTop(linkLabel);
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    private void showMenuIfNeeded(double x, double y) throws URISyntaxException {

        String js = String.format(getHrefJs, x, y);
        Object href = engine.executeScript(js);

        if (href != null && href.toString().length() > 0) {
            link = new URI(engine.getLocation()).resolve(href.toString()).toString();
            contextMenu.show(webView, Side.TOP, x, y);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.