gpt4 book ai didi

JavaFX 等待 Webview 完全加载或在 15 秒后取消所有内容

转载 作者:行者123 更新时间:2023-12-05 01:06:50 24 4
gpt4 key购买 nike

我正在用 JavaFX 编写一个 nfcreader 程序。使用 ACR122U nfcreader 和 github 上的 nfcreader 类。它按预期工作,现在我将卡放在读卡器上,在读取卡 uid 后,它会从我们的服务器加载一个网页并显示信息。

问题:

  • NFC 读卡器在后台任务中运行,如果读卡器上有卡,则始终触发。我需要防止这种情况发生 - 在网页加载时。

我做了什么:

  • 如果 nfcread 服务成功,它会调用方法“loadZeitdatenToWebview(nfcuid)”
  • 在这个方法中,一个变量被设置为 true 来告诉 Java webview 仍然加载数据
  • 如果 webview 的 Workerstate 成功,我将此变量设置为 false,否则它为 true... 持续 15 秒,由 pausetransition 检查 - 如果我在 15 秒内没有获得 webview“成功”,它将取消整个 nfcread并告诉用户没有连接到服务器 - 到目前为止
  • 如果我没有连接到服务器,它会正常工作,它会停止 nfcread 并且一切都很好
  • 但如果我获得了 webview 成功 - 它只能工作一次......我必须等待 15 秒(从暂停转换开始),直到它再次读取并向我显示网页。所以暂停过渡不是实现我需要的最佳方式:( - 但还有什么可以使用的?简而言之:readnfc -> 从卡中获取 uid -> webview 调用页面 dep。在 uid 上 -> 在网页完全加载并显示给用户之前,不应有其他 nfcreader -> 如果 15 秒后没有与服务器的连接,请停止一切​​...

nfcread 的代码成功...:

 nfcread.setOnSucceeded(new EventHandler<WorkerStateEvent>() { //if service succeeded

@Override
public void handle(WorkerStateEvent event) {
labelReaderStatus.setText("NFC Readerstatus: warte auf NFC");
labelReaderStatusInfo.setStyle("-fx-background-color: WHITE; -fx-text-fill: black;");
labelReaderStatusInfo.setText("warte...");

System.out.println("NFC UID Card: " + nfcread.getValue()); //return value from service nfcread
if (nfcread.getValue() != "" && nfcread.getValue() != "Error" && nfcread.getValue() != null && nfcread.getValue() != "Error no Card") {
uidRead = nfcread.getValue();

labelReaderStatusInfo.setText("NFC Chip wurde gelesen - beginne mit Auswertung ");
labelReaderStatusInfo.setStyle("-fx-background-color: GREEN; -fx-text-fill: white;");
//chekc if webengine still loads data if not loadmethod
//loadData to webview

if (!waitForData) {
loadZeitdatenToWebview(uidRead);
} else {
System.out.println("Still loading data for "+uidRead);
nfcread.reset();

}


} //wenn uidRead keinen Fehler und nicht leer ist
else if (nfcread.getValue() == "Error") {...

这里是等待 webview 或停止的代码...

//start webengine
private void loadZeitdatenToWebview(String uid) {


//wait till page loaded:
engine = webviewer.getEngine();
engine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {


if (newState == Worker.State.SUCCEEDED) {
System.out.println("Workerstate Succeeded");
System.out.println("waitforData: " +waitForData );
// new page has loaded, process:
this.waitForData = false;
zeiterfassungErfolgreich();

System.out.println("waitforData done reset: " +waitForData );

}
if (engine.getLoadWorker().getState() != Worker.State.RUNNING) {
System.out.println("Workerstate Running ");
System.out.println("load state while data request:" + engine.getLoadWorker().getState()); //SCHEDULED
this.waitForData = true;
zeiterfassungRunning();
}

});

engine.load(httpHostforZeiterfassung + uid);
//engine.load("http://10.0.0.11/nfcread.php?uid=" + uid);
System.out.println("here: " + engine.getLoadWorker().getState());
}


private void zeiterfassungErfolgreich() {
System.out.println("zeiterfassungErfolgreich");
System.out.println("Fertig:" +waitForData);
labelReaderStatusInfo.setText("Zeiterfassung erfolgreich...");
//nfcread.reset();
}

private void zeiterfassungRunning() {
System.out.println("zeiterfassungRunning check - for data within 15 seconds");
//engine.getLoadWorker().cancel();
PauseTransition pause = new PauseTransition(Duration.seconds(15));

if (engine.getLoadWorker().getState() != Worker.State.SUCCEEDED) pause.setOnFinished(event -> {
if (engine.getLoadWorker().getState() == Worker.State.SUCCEEDED) {pause.stop(); waitForData=false; }
else {
engine.executeScript("window.stop()");
waitForData = false;
labelReaderStatusInfo.setStyle("-fx-background-color:red; -fx-text-fill: white;");
labelReaderStatusInfo.setText("Error keine Verbindung zum Server!");
nfcread.cancel();
}
//System.out.println("Running:" +waitForData);
});
pause.play();
System.out.println("here2: " + engine.getLoadWorker().getState());


}


//end webengine

如果我可以通过这种方式使用 pausetransition,如果 webview 成功或者更好,我该如何防止等待时间?我应该使用什么来完成这项工作?感谢@all 这里!!

附加信息:如果我尝试在这 15 秒内创建一张卡片,我的实际代码会给我这个输出:

  • 等待一张卡片..
  • 关闭失败
  • 事件:0BDF8D69
  • 数据请求时的加载状态:SCHEDULED
  • zeiterfassung 运行检查 - 15 秒内的数据
  • 这里2:预定
  • 这里:正在运行
  • 等待一张卡片..
  • zeiterfassungErfolgreich
  • Fertig:真
  • 数据请求时的加载状态:SUCCEEDED
  • zeiterfassung 运行检查 - 15 秒内的数据
  • 这里2:成功
  • 关闭失败
  • 事件:0BDF8D69
  • 仍在加载数据等待卡片。 << 最后一行显示不允许加载新内容...

最佳答案

您的代码中至少有几个问题可能会导致您的整体问题。

  1. 你不会在加载成功(或失败)时停止PauseTransition

    看起来有人尝试实现这一点,但您在动画的 onFinished 处理程序中执行此操作。该处理程序在动画完成时调用,因此已经停止/停止。在该处理程序中调用 stop() 基本上是无操作的。

    重用单个 PauseTransition 实例并简单地根据 load worker 的运行状态启动和停止它可能会更容易(例如,通过观察 worker 的 running属性(property))。您也可以使用 worker 的运行状态而不是您自己的 waitForData 标志。

  2. 每次加载新网页时,您都会向工作人员的 state 属性添加一个新的监听器,但不会删除旧的监听器。

    这意味着监听器内部的工作是重复的,其中重复的次数会随着时间的推移而增加。首次初始化所有内容时,您应该只添加一次监听器。

在某些方面,我认为您的思维过于线性。通常 GUI 编程是事件驱动的,它本质上是异步的。

这是我在上面和问题评论中暗示的一个骨架示例。您显然需要重写一些东西才能将其集成到您的应用程序中,但它应该可以帮助您了解正在发生的事情并希望找到解决方案。

import javafx.animation.PauseTransition;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.scene.web.WebView;
import javafx.util.Duration;

public class Foo {

private final String baseUrl;
private final PauseTransition timeout;
private final WebView webView;

public Foo(String baseUrl) {
this.baseUrl = baseUrl;
timeout = new PauseTransition(Duration.seconds(15));
webView = new WebView();

Worker<?> worker = webView.getEngine().getLoadWorker();
// observe 'running' property to start/stop timeout
worker.runningProperty().addListener(this::loaderRunningChanged);
// observe 'state' property to handle success/failure
worker.stateProperty().addListener(this::loaderStateChanged);

timeout.setOnFinished(
e -> {
worker.cancel(); // stop trying to load
handleTimeout();
});
}

public void loadData(String uid) {
if (!webView.getEngine().getLoadWorker().isRunning()) {
webView.getEngine().load(baseUrl + uid);
}
}

private void loaderRunningChanged(
ObservableValue<? extends Boolean> obs, boolean wasRunning, boolean isRunning) {
if (isRunning) {
System.out.println("Loading...");
timeout.playFromStart(); // restart timeout countdown
} else {
timeout.stop(); // load completed, stop timeout countdown
}
}

private void loaderStateChanged(
ObservableValue<? extends State> obs, State oldState, State newState) {
// switch expressions standardized in Java 14 (preview feature in Java 12 and 13)
switch (newState) {
case SUCCEEDED -> handleSuccess();
case FAILED -> handleFailure();
}
}

private void handleSuccess() {
System.out.println("Load succeeded.");
// ...
}

private void handleFailure() {
System.out.println("Load failed.");
// ...
}

private void handleTimeout() {
System.out.println("Load timeout.");
// ...
}
}

关于JavaFX 等待 Webview 完全加载或在 15 秒后取消所有内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68367752/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com