如何在JavaFX服务内安全地更新JavaFX GUI上的小部件?我记得在使用Swing进行开发时,我通常会使用“invoke later”和其他各种Swing工具来确保所有UI更新都在Java事件线程中安全处理。这是一个处理数据报消息的简单服务线程示例。缺少的部分是解析数据报消息和更新对应UI小部件的部分。可以看到,服务类非常简单。
我不确定是否需要使用简单绑定属性(例如消息),或者是否应该将小部件传递给我的StatusListenerService的构造函数(这可能不是最好的选择)。能否给我一个类似的好示例供参考。
public class StatusListenerService extends Service<Void> {
private final int mPortNum;
/**
*
* @param aPortNum server listen port for inbound status messages
*/
public StatusListenerService(final int aPortNum) {
this.mPortNum = aPortNum;
}
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
updateMessage("Running...");
try {
DatagramSocket serverSocket = new DatagramSocket(mPortNum);
// allocate space for received datagrams
byte[] bytes = new byte[512];
//message.setByteBuffer(ByteBuffer.wrap(bytes), 0);
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
while (!isCancelled()) {
serverSocket.receive(packet);
SystemStatusMessage message = new SystemStatusMessage();
message.setByteBuffer(ByteBuffer.wrap(bytes), 0);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
updateMessage("Cancelled");
return null;
}
};
}
}
PacketData
的类中,虽然您显然会为其取一个更有意义的名称。然后只需在侦听器中解包数据并相应地更新UI即可。 - James_Dnull
(更新值)。请注意,我仍然拥有相同的while
循环:它可以运行任意长时间。但是,随着数据包的处理,它也会更新值,并且该值仍然可以从 UI 中观察到。实际上,您可能根本不需要Service
,而只需使用单个Task
,尽管您可能希望在用户取消后重新启动。这基本上是Task
文档 中“返回部分结果的任务”的示例。 - James_D