【发布时间】:2019-01-28 05:09:42
【问题描述】:
在我的 JavaFX 项目中,我在 WebView 的 WebEngine 上有一个监听器,它等待网站完全呈现。然后我需要访问生成的 DOM 文档。如果我不知道侦听器属于哪个 WebEngine,这将不起作用!
创建一个变量或简单地使用存在的webView 不是一种选择!这是因为我正在使用 ChangeListeners 创建几个 webView。
我现在如何将它们分配给彼此?
webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
if (newState == Worker.State.SUCCEEDED) {
// Here I do my stuff
// I need to access webView.getEngine().getDocument()
}
}
});
更新
这是我面临的问题的最小工作示例:https://github.com/mg98/StackOverflow-Demonstration
它基本上是关于: Main.java
package sample;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import org.w3c.dom.Document;
public class Main extends Application {
private static Controller ctrl;
private final static String[] urls = new String[] {
"https://google.com",
"https://youtube.com",
"https://facebook.com",
"https://twitter.com",
"https://stackoverflow.com"
};
@Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root = fxmlLoader.load();
ctrl = fxmlLoader.getController();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
findSomething();
}
public static void main(String[] args) {
launch(args);
}
private void findSomething() {
for (int i = 0; i < 5; i++) {
System.out.println("Request to " + urls[i]);
WebView webView = ctrl.createWebView();
webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
if (newState == Worker.State.SUCCEEDED) {
// The BIG QUESTION is: What is the corresponding WebEngine to call?
Document doc = webView.getEngine().getDocument();
// As you will see, the responses print in totally random order
System.out.println(doc.getElementsByTagName("title").item(0).getTextContent());
}
}
});
webView.getEngine().load(urls[i]);
}
}
}
Controller.java
package sample;
import javafx.fxml.FXML;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
public class Controller {
@FXML
private VBox browsers;
@FXML
protected void initialize() {
}
WebView createWebView() {
WebView webView = new WebView();
browsers.getChildren().add(webView);
return webView;
}
}
sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<GridPane alignment="center" hgap="10" vgap="10" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/9" fx:controller="sample.Controller">
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
<VBox fx:id="browsers" prefHeight="200.0" prefWidth="100.0" />
</children>
</GridPane>
【问题讨论】:
-
您的问题不清楚。展示你所拥有的演示。
-
@Sedrick 对不起。基本上我只需要访问分配给监听器的 WebEngine 的 ChangeListener 更改方法。
-
请提供一个minimal reproducible example 来说明问题。反正你注册监听器的时候好像就有引擎了,为什么不在里面也用呢?
-
从您的代码中,您可以简单地在
changed方法中调用webView.getEngine().getDocument()。