2016-07-15 142 views
0

我想实现一个简单的浏览器,使用FXCanvas的SWT应用程序内使用JavaFX WebView/WebEngine。出于某种原因,内置的上下文菜单(类似刷新复制/粘贴等)似乎没有工作。JavaFX WebView上下文菜单

如果我创建了自己的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/web视图中的错误?

回答

1

只需使用JSObject程序,通过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; 
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(); 
      } 
     }); 
    } 
}