我有一个JavaFX WebView,并希望从webview中显示的“test.html”中调用类“JavaBridge”的方法“hello”。 为什么这不起作用?我确保只有在完全呈现页面时才将“bridge”对象添加到window.object中,这可能不是问题所在。我也看不到HTML的任何问题。
以下是HTML代码(“test.html”):
<html>
<head>
</head>
<body>
<a href="#click" onclick="bridge.hello()">call java</a>
</body>
</html>
这是Java代码:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
java.net.URI uri = java.nio.file.Paths.get("test.html").toAbsolutePath().toUri();
WebView root = new javafx.scene.web.WebView();
root.getEngine().load(uri.toString());
root.getEngine().
getLoadWorker().
stateProperty().
addListener(new ChangeListener < State > () {
@Override public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.SUCCEEDED) {
System.out.println("READY");
JSObject jsobj = (JSObject) root.getEngine().executeScript("window");
jsobj.setMember("bridge", new JavaBridge());
}
}
});
primaryStage.setScene(new javafx.scene.Scene(root, 800, 600));
primaryStage.show();
}
}
class JavaBridge {
public void hello() {
System.out.println("hello");
}
}
答案 0 :(得分:3)
你的内部类应该在主类中。它应该是公开的。像这样:
import java.net.URL;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
final URL url = getClass().getResource("test.html");
WebView root = new javafx.scene.web.WebView();
root.getEngine().load(url.toExternalForm());
root.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.SUCCEEDED) {
System.out.println("READY");
JSObject jsobj = (JSObject) root.getEngine().executeScript("window");
jsobj.setMember("bridge", new JavaBridge());
}
}
});
primaryStage.setScene(new javafx.scene.Scene(root, 800, 600));
primaryStage.show();
}
public class JavaBridge {
public void hello() {
System.out.println("hello");
}
}
}
答案 1 :(得分:1)
在Java 10.0.2上使用此桥接器功能时,我注意到它无法始终如一地工作。 Javascript调用并非一直有效。
经过研究,我发现了与Java Garbage Collector相关的OpenJDK错误,该错误似乎也发生在常规JDK上: https://bugs.openjdk.java.net/browse/JDK-8170085
实际上,根据https://docs.oracle.com/javase/9/docs/api/javafx/scene/web/WebEngine.html,建议将网桥存储到变量中,以避免Java GC收集对象。
在向类添加私有变量后,从JS到Java的调用一直在我的应用程序中开始工作。
答案 2 :(得分:0)
我有同样的问题,解决此问题的唯一方法是将Bridge存储在静态变量中。 这是一个使用javafx FileChooser的示例。
active environment : base
active env location : C:\ProgramData\Miniconda
shell level : 1
user config file : C:\Users\[username]\.condarc
populated config files :
conda version : 4.5.12
conda-build version : not installed
python version : 3.7.0.final.0
base environment : C:\ProgramData\Miniconda (writable)
channel URLs : https://repo.anaconda.com/pkgs/main/win-64
https://repo.anaconda.com/pkgs/main/noarch
https://repo.anaconda.com/pkgs/free/win-64
https://repo.anaconda.com/pkgs/free/noarch
https://repo.anaconda.com/pkgs/r/win-64
https://repo.anaconda.com/pkgs/r/noarch
https://repo.anaconda.com/pkgs/pro/win-64
https://repo.anaconda.com/pkgs/pro/noarch
https://repo.anaconda.com/pkgs/msys2/win-64
https://repo.anaconda.com/pkgs/msys2/noarch
package cache : C:\ProgramData\Miniconda\pkgs
C:\Users\[username]\AppData\Local\conda\conda\pkgs
envs directories : C:\ProgramData\Miniconda\envs
C:\Users\[username]\AppData\Local\conda\conda\envs
C:\Users\[username]\.conda\envs
platform : win-64
user-agent : conda/4.5.12 requests/2.19.1 CPython/3.7.0 Windows/10 Windows/10.0.17134
administrator : False
netrc file : None
offline mode : False