Java 使用WebEngine执行多个脚本(或依赖于其他脚本的脚本)
我想使用WebEngine(JavaFX)在网页上执行一些JavaScript(和jQuery)并处理结果(使用Java代码)。Java 使用WebEngine执行多个脚本(或依赖于其他脚本的脚本),java,jquery,javafx,jquery-callback,javafx-webengine,Java,Jquery,Javafx,Jquery Callback,Javafx Webengine,我想使用WebEngine(JavaFX)在网页上执行一些JavaScript(和jQuery)并处理结果(使用Java代码)。 我有一个回调函数的问题,它们自己执行一些脚本 为了尽可能简单地说明我的问题,我制作了一个最小化的代码来显示不想要的结果(它只是更大项目的一部分) 因此,我创建了三个类: 浏览器-包装web引擎的类,用作加载网页和执行脚本的浏览器 JQueryFunction-一个类,列出了两个与jQuery回调函数一起使用的函数,可以通过多种方式实现。(基本上,它们应该是用户以自己的
我有一个回调函数的问题,它们自己执行一些脚本 为了尽可能简单地说明我的问题,我制作了一个最小化的代码来显示不想要的结果(它只是更大项目的一部分) 因此,我创建了三个类:
executeScript
会按预期运行,并更改某些元素的文本(在索引编号之前)。但是第二个
executeScript
被永远粘住了,粘住了GUI,实际上粘住了整个JavaFX应用程序
我理解为什么会发生这种情况……executeScript
方法调用WebEngine(通过平台.runLater
)来执行jQuery,该jQuery迭代元素并调用Java函数(每次使用不同的参数)
- 第一次执行(调用function1)从function1获取返回的字符串,并将其应用于元素的文本。(完全出乎意料)
- 第二次执行(调用function2)执行调用Java函数的jQuery函数,但是Java函数需要执行更多的JavaScript(或jQuery),但是WebEngine在第一次执行完成之前不会执行。
但是第一次执行不会完成,因为它取决于第二次执行的结果
为什么WebEngine仅限于在JavaFX应用程序下工作?
为什么它必须只与一个线程一起工作?避免出现“死锁”的一种可能方法是,当您已经在GUI线程(JavaFX应用程序线程)中运行时,不要调用
Platform.runLater
。比如:
public static Object executeScript(String script) throws InterruptedException, ExecutionException {
if(Platform.isFxApplicationThread()) {
return webEngine.executeScript(script);
}
FutureTask<Object> task = new FutureTask<>(new Callable<Object>() {
@Override
public Object call() throws Exception {
return webEngine.executeScript(script);
}
});
Platform.runLater(task);
return task.get();
}
公共静态对象executeScript(字符串脚本)引发InterruptedException,ExecutionException{
if(Platform.isFxApplicationThread()){
返回webEngine.executeScript(脚本);
}
FutureTask task=新的FutureTask(新的可调用(){
@凌驾
公共对象调用()引发异常{
返回webEngine.executeScript(脚本);
}
});
Platform.runLater(任务);
return task.get();
}
import java.util.concurrent.ExecutionException;
public class JQueryFunction {
public String function1(int index, String text) {
return (index+1) + ": " + text;
}
public String function2(int index, String text) throws InterruptedException, ExecutionException {
return (String) Browser.executeScript("$($(\".BlueArrows:eq(2) li\").find(\"a:first\")[index]).text();");
}
}
public class Test {
public static void main(String[] args) throws Exception {
Browser.start();
Thread.sleep(1000); // Only used here to simplify the code
Browser.load("https://docs.oracle.com/javase/tutorial/");
Thread.sleep(3500); // Only used here to simplify the code
Browser.getWindow().setMember("javaApp", new JQueryFunction());
Browser.executeScript("$(\".BlueArrows:eq(0) li\").find(\"a:first\").text(function(index, text) { return javaApp.function1(index, text); });");
Browser.executeScript("$(\".BlueArrows:eq(0) li\").find(\"a:first\").text(function(index, text) { return javaApp.function2(index, text); });");
}
}
public static Object executeScript(String script) throws InterruptedException, ExecutionException {
if(Platform.isFxApplicationThread()) {
return webEngine.executeScript(script);
}
FutureTask<Object> task = new FutureTask<>(new Callable<Object>() {
@Override
public Object call() throws Exception {
return webEngine.executeScript(script);
}
});
Platform.runLater(task);
return task.get();
}