gpt4 book ai didi

java - 在线程中使用 Javafx TimeLine

转载 作者:行者123 更新时间:2023-11-30 07:46:01 29 4
gpt4 key购买 nike

我正在尝试创建一个 Internet 检查器类,它将检查与某个 url 的连接并相应地更新状态属性。为了避免 ui 卡住,我想使用一个线程和一个计时器在一定时间间隔后重新检查。问题是时间轴关键帧中的 CHECK 方法调用仍然是从 FX 线程调用的。我如何在线程中使用时间轴?

代码:

public class InternetChecker {
private String baseUrl;
/***Properties***/
private ObjectProperty<Status> status = new SimpleObjectProperty<>(Status.ACTIVE);

/****************************************************************
********** CONSTRUCTORS ************
****************************************************************/
public InternetChecker(String baseUrl) {
this(baseUrl, 1000);
}

public InternetChecker(String baseUrl, int millisCheckInterval) {
this.baseUrl = baseUrl;
new Thread(() -> {
Timeline timelineCheck = new Timeline();
timelineCheck.getKeyFrames().add(
new KeyFrame(Duration.millis(millisCheckInterval), e -> {
check();
}));
timelineCheck.setCycleCount(Animation.INDEFINITE);
timelineCheck.play();
}).start();
}

/*******************************
* Will check if there is an internet connection present
* and update the status accordingly
*******************************/
public void check() {
// Check if base internet connection
// is working, if it is we continue
// to see if domain connection is working
try {
if ("127.0.0.1".equals(InetAddress.getLocalHost().getHostAddress())) {
setStatus(Status.INTERNET_DISCONNECTED);
return;
}
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
// Check if base domain connection is working
try {
final URL url = new URL(baseUrl);
final URLConnection conn = url.openConnection();
conn.connect();
conn.getInputStream().close();
setStatus(Status.ACTIVE);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
setStatus(Status.BASE_URL_UNREACHABLE);
}
}

/****************************************************************
********** ACCESSORS ************
****************************************************************/

public Status getStatus() {
return status.get();
}

public ObjectProperty<Status> statusProperty() {
return status;
}

private void setStatus(Status status) {
this.status.set(status);
}

/*******************************
* ACTIVE (Base url reachable)
* BASE_URL_UNREACHABLE (Internet available, but base url is unreachable)
* INTERNET_DISCONNECTED (Internet is not available)
********************************/
public enum Status {
ACTIVE,
BASE_URL_UNREACHABLE,
INTERNET_DISCONNECTED;
}
}

最佳答案

由于您需要定期执行与JavaFX 应用程序线程 通信的后台 任务,因此最好使用ScheduledService。 .此类执行(新)Task定期使用可由开发人员定义的 Executor。请注意,ScheduledService 扩展了 javafx.concurrent.Service

以下是您需要执行的操作的框架示例:

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;

public class ConnectionStatusService extends ScheduledService<Status> {

// Property allows you to change the "baseUrl" between executions
private final StringProperty baseUrl = new SimpleStringProperty(this, "baseUrl");

// property getter and setters omitted...

@Override
protected Task<Status> createTask() {
// creates a new Task and gives the current "baseUrl"
// as an argument. This is called every cycle
return new ConnectionStatusTask(getBaseUrl());
}

private static class ConnectionStatusTask extends Task<Status> {

// A Task is a one-shot thing and its initial state should be
// immutable (or at least encapsulated from external modification).
private final String baseUrl;

private ConnectionStatusTask(String baseUrl) {
this.baseUrl = baseUrl;
}

@Override
protected Status call() throws Exception {
// Do what you need to determine connection status
return computedStatus;
}
}

}

然后你会监听/绑定(bind)到 lastValue属性(property)。

public void initService() {
ConnectionStatusService service = new ConnectionStatusService();
service.setBaseUrl(/* your URL */);
service.setPeriod(Duration.seconds(1)); // run every 1 seconds
service.lastValueProperty().addListener(/* your listener */); // or bind to this property

// you may also want to add EventHandlers/Listeners to handle when the
// service fails and such.
service.start();
}

观察 lastValue 属性而不是 value 属性很重要。 lastValue的Javadoc中给出了原因:

The last successfully computed value. During each iteration, the "value" of the ScheduledService will be reset to null, as with any other Service. The "lastValue" however will be set to the most recently successfully computed value, even across iterations. It is reset however whenever you manually call reset or restart.

我建议阅读 TaskServiceScheduledService 的 Javadoc 以获得更多信息。所有这三个类都实现了 javafx.concurrent.Worker 接口(interface)。

关于java - 在线程中使用 Javafx TimeLine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51109833/

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