gpt4 book ai didi

JavaFX : two bound properties for Task

转载 作者:搜寻专家 更新时间:2023-11-01 02:05:25 25 4
gpt4 key购买 nike

我有一个 JavaFX 8 应用程序,希望允许一个任务修改两个不同的 UI 元素。据我了解,如果我要修改单个标签,我可以使用 mylabel.textProperty().bind(mytask.messageProperty()) 绑定(bind)到标签,并在任务中使用 updateMessage()。

如何使用两种不同的任意类型来做到这一点?我查看了并发和 JavaFX 文档中的示例,但对我来说它们并没有很好地解释这一点。

我理解任务本身具有消息(字符串)、进度(双/长)、标题(字符串)和值(用户定义)属性,但是如果我想要两个或更多任意类型 我自己的用于控制 UI 元素的属性? (并希望避免使用 runLater()。)

我可以在任务上创建任意属性吗?我觉得我遗漏了一些明显的东西。

最佳答案

建议

如果您的任务需要自定义属性的属性样式界面,请仅使用以下解决方案。通常,许多应用程序不需要这样的接口(interface)和单个 Platform.runLater调用而不是公开自定义属性就足够了。

解决方案

您可以使用与 message property 相同的成语的 Task .我只是将相关代码复制并粘贴到这个答案中。请注意,此解决方案将通过 AtomicReference 来“合并更新,这样我们就不会淹没事件队列”。 .此解决方案不违背 JavaFX 的一般绑定(bind)性质,如果使用过于频繁,也不会导致主线程产生大量消息。但是,因为它合并了更新,所以并非对属性的每次更新都会触发属性更改。每个 pulse 最多只触发一次属性更改.

private final StringProperty message = new SimpleStringProperty(this, "message", "");
@Override public final String getMessage() { checkThread(); return message.get(); }
@Override public final ReadOnlyStringProperty messageProperty() { checkThread(); return message; }

/**
* Used to send message updates in a thread-safe manner from the subclass
* to the FX application thread. AtomicReference is used so as to coalesce
* updates such that we don't flood the event queue.
*/
private AtomicReference<String> messageUpdate = new AtomicReference<>();

/**
* Updates the <code>message</code> property. Calls to updateMessage
* are coalesced and run later on the FX application thread, so calls
* to updateMessage, even from the FX Application thread, may not
* necessarily result in immediate updates to this property, and
* intermediate message values may be coalesced to save on event
* notifications.
* <p>
* <em>This method is safe to be called from any thread.</em>
* </p>
*
* @param message the new message
*/
protected void updateMessage(String message) {
if (isFxApplicationThread()) {
this.message.set(message);
} else {
// As with the workDone, it might be that the background thread
// will update this message quite frequently, and we need
// to throttle the updates so as not to completely clobber
// the event dispatching system.
if (messageUpdate.getAndSet(message) == null) {
runLater(new Runnable() {
@Override public void run() {
final String message = messageUpdate.getAndSet(null);
Task.this.message.set(message);
}
});
}
}
}

// This method exists for the sake of testing, so I can subclass and override
// this method in the test and not actually use Platform.runLater.
void runLater(Runnable r) {
Platform.runLater(r);
}

// This method exists for the sake of testing, so I can subclass and override
// this method in the test and not actually use Platform.isFxApplicationThread.
boolean isFxApplicationThread() {
return Platform.isFxApplicationThread();
}

其他问题的答案

this is the source code from class Task?

是的。这是 source code from Task .

So you're saying the only way is to extend the Task class with additional properties like is done in Task above?

好吧,如果您希望自定义任务中的自定义属性可以同时修改,那么是的,您需要对任务进行子类化。但这与将自定义属性添加到您定义的任何其他类(或扩展另一个现有类以添加属性)并没有太大区别。唯一的区别是额外的机制可确保在正确的线程上执行并在需要时合并。

Second topic, you also seem to say at the start that occasionally calling runLater is an acceptable way to do it?

是的,Platform.runLater()是在任务和 JavaFX UI 线程之间发送消息的推荐方式(如 Task javadoc 中所示)。

这些属性提供了任务和对象之间的松散耦合,这些对象可能通过 observer pattern 依赖于任务。 .如果您不需要松散耦合,那么您就不需要特别需要属性(尽管它们有时很有用且易于绑定(bind),因为 JavaFX API 的其余部分(例如标签的文本)是基于属性的) .

关于JavaFX : two bound properties for Task,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36020573/

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