嘿,我已经有一段时间了。从到目前为止我看到的所有示例中,我似乎都无法正确理解它。似乎很容易,但我很茫然。
我的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')");
答案 0 :(得分:1)
要从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方法,例如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