问题
I am trying to implement a simple browser using the JavaFX WebView/WebEngine inside of an SWT application using the FXCanvas. For some reason, the inbuilt context menu (with things like Refresh Copy/Paste etc.) does not seem to be working.
If I create my own JavaFX context menu then it works, but I can't find a way to determine what HTML element is under the mouse at a given point (i.e. to have different menu items for links vs. images)
A simple example that shows this behavior:
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();
}
});
}
}
Am I doing something wrong, or is this a bug with FXCanvas/WebView?
回答1:
Just use JSObject from JavaFx to get the selected html element....
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();
}
});
}
}
来源:https://stackoverflow.com/questions/38391522/javafx-webview-context-menu