Java Swing webEngine.executeScript无法在HTML Javafx Webview中触发

时间:2019-04-05 18:55:29

标签: java eclipse javafx webview

嘿,我已经有一段时间了。从到目前为止我看到的所有示例中,我似乎都无法正确理解它。似乎很容易,但我很茫然。

我的HTML:

WebView webView = new WebView();

webView.getEngine().setJavaScriptEnabled(true);
webView.setContextMenuEnabled(false);
webView.getEngine().loadContent(""+
"<!DOCTYPE html>\r\n" + 
    "<html>\r\n" + 
        "<head>\r\n" + 
        "</head>\r\n" +
        "<body>" +
                    "<div class=\"chatbox\" style=\"document.body.style.overflow = 'hidden';\">\r\n" + 
                    "       <div class=\"chatlogs\">\r\n" + 
                    "           <div class=\"animated animatedFadeInUp fadeInUp\">" +
                    "                   <div class=\"chat friend\">\r\n" + 
                    "                   <div class=\"user-photo\"><img src=\"" + pic1 + "\"></div>\r\n" + 
                    "                   <p class=\"chat-message\">Whats up!</p>\r\n" + 
                    "                   <span class=\"timefriend\">11:01pm Oct 25 2019</span>\r\n" + 
                    "               </div>\r\n" + 
                    "           </div>" +
                    "           <div class=\"animated animatedFadeInUp fadeInUp\">" +
                    "               <div class=\"chat self\">\r\n" + 
                    "                   <div class=\"user-photo\"><img src=\"" + pic2 + "\"></div>" + 
                    "                   <p class=\"chat-message\">Not much yo!</p>\r\n" + 
                    "                   <span class=\"timeself\">11:01 PM | Oct 11 2019</span>\r\n" + 
                    "               </div>\r\n" + 
                    "           </div>\r\n" + 
                    "           <div class=\"animated animatedFadeInUp fadeInUp\">" +
                    "               <div class=\"chat friend\">\r\n" + 
                    "                   <div class=\"user-photo\"><img src=\"" + pic1 + "\"></div>" + 
                    "                   <p class=\"chat-message\">Whats up!</p>\r\n" + 
                    "                   <span class=\"timefriend\">11:01 PM | Oct 11 2019</span>\r\n" + 
                    "               </div>\r\n" + 
                    "           </div>\r\n" + 
                    "           <div class=\"animated animatedFadeInUp fadeInUp\">" +
                    "               <div class=\"chat friend\">\r\n" + 
                    "                   <div class=\"user-photo\"><img src=\"" + pic1 + "\"></div>" + 
                    "                   <p class=\"chat-message\">Whats up!</p>\r\n" + 
                    "                   <span class=\"timefriend\">11:01 PM | Oct 11 2019</span>\r\n" + 
                    "               </div>\r\n" + 
                    "           </div>\r\n" + 
                    "           <div id=\"nextChatHolder\"></div>" +
                    "       </div>\r\n" + 
                    "   </div>\r\n" +
                    "   <div class=\"footer\"></div>" + 
                    "   <script language=\"javascript\">\r\n" + 
                    "       function app.test() {\r\n" + 
                    "           window.scrollBy(0, 20); \r\n" + 
                    "           alert('done');\r\n" +
                    "       }\r\n" + 
                    "   </script>" +
                    "</body>\r\n" + 
                "</html>");

这是我正在使用的Java(并试图开始工作):

webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>()
            {
                public void changed(ObservableValue<? extends State> o, State old, final State state)
                {
                    if (state == State.SUCCEEDED)
                    {
                        JSObject win = (JSObject) webView.getEngine().executeScript("window");
                        win.setMember("app", new JavaApp());
                        //webView.getEngine().executeScript("javaObj.start()");
                    }
                }
            });

private class JavaApp {
        public void test() {
            Platform.exit();
        }
    }

我想这样做:

function app.test() {\r\n" + 
    window.scrollBy(0, 20); \r\n" + 
    alert('done');\r\n" +
}

并通过以下方式调用它:

webView.getEngine().executeScript("test()");

这也不行..... /

webView.getEngine().executeScript("alert('testing')");

1 个答案:

答案 0 :(得分:1)

从JavaScript调用Java方法

要从JavaScript调用Java方法JavaApp#test(),实现的最重要部分已包含在您的 second 代码段中。例如,仅呼叫本身仍然丢失。

<button onclick='app.test();'>Call JavaApp#test-method</button>

但是,必须考虑两个重要事项:首先,嵌套类JavaApp 必须public。其次,应用程序必须保留对JavaApp实例的引用,这是从JavaScript回调执行该方法所必需的(请参见here,第Calling back to Java from JavaScript节)。

因此,您必须按以下步骤修改代码:

JavaApp javaApp = new JavaApp();             // Hold a reference...
webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
    public void changed(ObservableValue<? extends State> o, State old, final State state) {
        if (state == State.SUCCEEDED) {
            JSObject win = (JSObject) webView.getEngine().executeScript("window");
            win.setMember("app", javaApp);   // Use the reference...
        }
    }
});

public class JavaApp {                       // Change the access modifier from private to public...
    public void test() {
        Platform.exit();
    }
}

从Java调用JavaScript方法

如果要从Java调用JavaScript方法,例如test(),这是通过

完成的
webView.getEngine().executeScript("test()");

作为示例,我使用您的第三代码段中给出的test()方法,但是名称必须app.test()更改为test()。如果调用webView.getEngine().executeScript("test()");,则test()方法的例外情况是 。这是因为对于某些JavaScript方法(例如alert()),window.alert()将请求转发到回调(对于WebEngine,则是回调onAlert)。如果未定义回调,则该请求将被忽略(请参见here用户界面回调部分)。例如,window.alert()的回调可以定义如下:

alert()

其中webView.getEngine().setOnAlert(event -> showAlert(event.getData())); 是自定义方法,而showAlert(String msg)包含原始消息(对于msg方法而言,是done),例如:

test()

您可以在How can I make JavaFX web browser displays alert and confirm message中找到更多示例。

编辑:

从JavaScript调用Java方法的示例代码:按下按钮时,从JavaScript调用Java方法private void showAlert(String msg){ Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle("Custom Alert"); alert.setHeaderText(""); alert.setContentText(msg); alert.showAndWait(); } ,这将在文本区域中输出文本JavaApp#test()

done

从Java调用JavaScript方法的示例代码:按下按钮时,从Java调用JavaScript方法import javafx.application.Application; import javafx.concurrent.Worker.State; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.TextArea; import javafx.scene.layout.VBox; import javafx.scene.web.WebEngine; import javafx.scene.web.WebView; import javafx.stage.Stage; import netscape.javascript.JSObject; public class WebViewExecuteJavaFromJavaScript extends Application { private TextArea textArea; private static String HTML_STRING = "" + "<!DOCTYPE html>\r\n" + "<html>\r\n" + " <head>\r\n" + " </head>\r\n" + " <body>" + " <button onclick='app.test();'>Call Java-method JavaApp#test()...</button>" + // Call Java-method JavaApp#test()... " </body>\r\n" + "</html>"; @Override public void start(final Stage stage) { WebView webView = new WebView(); WebEngine webEngine = webView.getEngine(); webEngine.setJavaScriptEnabled(true); webEngine.loadContent(HTML_STRING); JavaApp javaApp = new JavaApp(); webEngine.getLoadWorker().stateProperty().addListener((o, oldState, newState) -> { if (newState == State.SUCCEEDED) { JSObject win = (JSObject) webView.getEngine().executeScript("window"); win.setMember("app", javaApp); // Enable call of Java-method from JavaScript... } }); textArea = new TextArea(); textArea.setWrapText(true); VBox root = new VBox(); root.setPadding(new Insets(5)); root.setSpacing(5); root.getChildren().addAll(webView, textArea); Scene scene = new Scene(root); stage.setTitle("Demo: Execute Java from JavaScript"); stage.setScene(scene); stage.setWidth(450); stage.setHeight(300); stage.show(); } public static void main(String[] args) { launch(args); } public class JavaApp { public void test() { textArea.setText(textArea.getText() + "done "); } } } ,它在文本区域中输出文本test(),在对话框中。

done