【问题标题】:JavaFX WebView Context MenuJavaFX WebView 上下文菜单
【发布时间】:2016-11-18 09:26:10
【问题描述】:

我正在尝试在使用 FXCanvas 的 SWT 应用程序内部使用 JavaFX WebView/WebEngine 实现一个简单的浏览器。出于某种原因,内置的上下文菜单(包括刷新复制/粘贴等)似乎不起作用。

如果我创建自己的 JavaFX 上下文菜单,那么它可以工作,但我无法找到一种方法来确定给定点鼠标下的 HTML 元素(即,链接与图像具有不同的菜单项)

显示此行为的简单示例:

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import javafx.embed.swt.FXCanvas;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

public class TestBrowser {
    public static void main (String [] args) {
        Display display = new Display ();
        Shell shell = new Shell(display);

        shell.setLayout(new GridLayout());

        FXCanvas canvas = new FXCanvas(shell, SWT.NONE);
        canvas.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true));

        BorderPane borderPane = new BorderPane();
        Scene scene = new Scene(borderPane);
        canvas.setScene(scene);

        WebView browser = new WebView();
        WebEngine webEngine = browser.getEngine();
        borderPane.setCenter(browser);

//        createContextMenu(browser); Creating a custom context menu works

        boolean test = browser.isContextMenuEnabled();
        System.out.println("WebView context menu enabled? "+test);

        webEngine.load("http://example.org");

        shell.open ();
        while (!shell.isDisposed ()) {
            if (!display.readAndDispatch ()) display.sleep ();
        }
        display.dispose ();
    }

    private static void createContextMenu(WebView webView) {
        ContextMenu contextMenu = new ContextMenu();
        MenuItem reload = new MenuItem("Reload");
        reload.setOnAction(e -> webView.getEngine().reload());

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

是我做错了什么,还是 FXCanvas/WebView 的错误?

【问题讨论】:

    标签: java javafx swt javafx-webengine


    【解决方案1】:

    只需使用 JavaFx 中的 JSObject 即可获取选定的 html 元素....

    import org.eclipse.swt.SWT;
    import org.eclipse.swt.layout.GridData;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;
    
    import javafx.embed.swt.FXCanvas;
    import javafx.scene.Scene;
    import javafx.scene.control.ContextMenu;
    import javafx.scene.control.MenuItem;
    import javafx.scene.input.MouseButton;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.web.WebEngine;
    import javafx.scene.web.WebView;
    import netscape.javascript.JSObject;
    
    public class TestBrowser {
        public static void main (String [] args) {
            Display display = new Display ();
            Shell shell = new Shell(display);
    
            shell.setLayout(new GridLayout());
    
            FXCanvas canvas = new FXCanvas(shell, SWT.NONE);
            canvas.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true));
    
            BorderPane borderPane = new BorderPane();
            Scene scene = new Scene(borderPane);
            canvas.setScene(scene);
    
            WebView browser = new WebView();
            WebEngine webEngine = browser.getEngine();
            borderPane.setCenter(browser);
    
            createContextMenu(browser); //Creating a custom context menu works
    
            boolean test = browser.isContextMenuEnabled();
            System.out.println("WebView context menu enabled? "+test);
    
            webEngine.load("http://example.org");
    
            shell.open ();
            while (!shell.isDisposed ()) {
                if (!display.readAndDispatch ()) display.sleep ();
            }
            display.dispose ();
        }
    
    
    
        private static void createContextMenu(WebView webView) {
    
            MenuItem reload = new MenuItem("reload");
            reload.setOnAction(e -> {
                webView.getEngine().reload();
                }
            );
            ContextMenu contextMenu = new ContextMenu(reload);
            webView.setOnMousePressed(e -> {
                if (e.getButton() == MouseButton.SECONDARY) {
                    System.out.println( webView.getEngine().executeScript("document.elementFromPoint("
                            +e.getX()
                            +"," +  e.getY()+").tagName;"));
                    JSObject object = (JSObject) webView.getEngine().executeScript("document.elementFromPoint("
                            +e.getX()
                            +"," +  e.getY()+");");
                    contextMenu.show(webView, e.getScreenX(), e.getScreenY());
                } else {
                    contextMenu.hide();
                }
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-09
      • 2015-01-18
      • 1970-01-01
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多