我需要将一个SimpleMapProperty添加到JavaFX服务类,但是如果我使用正确的方法,我不确定正确的语法。请注意,我并不是想让JavaFX服务看起来像Java Bean,我只需要知道如何从枚举ModuleType(可以是TYPEA或TYPEB)和相关的布尔标志来监听EnumMap的更新。从本质上讲,这可以被认为是一对包含在单个EnumMap中的看门狗定时器。
我无法理解如何添加底层的EnumMap条目(上面描述的每个ModuleType应该有2个)。
public class UDPListenerService extends Service<Void> {
// 'watchdog' property
private final MapProperty<ModuleType, Boolean> watchdog;
// 'watchdog' SimpleMapProperty bound property getter
public ObservableMap<ModuleType, Boolean> getWatchdog() {
return watchdog.get();
}
// 'watchdog' SimpleMapProperty bound property setter
public void setWatchdog(ObservableMap<ModuleType, Boolean> aValue) {
watchdog.set(aValue);
}
// 'watchdog' SimpleMapProperty bound property
public MapProperty<ModuleType, Boolean> watchdogProperty() {
return watchdog;
}
/**
* Constructor
*/
public UDPListenerService()
{
this.watchdog = new SimpleMapProperty<>(
FXCollections.observableHashMap());
}
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
updateMessage("Running...");
while (!isCancelled()) {
try {
Thread.sleep(1000);
Platform.runLater(() -> {
try {
// update do some processing here
// . . .
// pet the watchdog
// setWatchdog
if (testforModuleType==ModuleType.TYPEA) {
// please help with syntax
setWatchdog(ModuleType.TYPEA, false);
} else {
// please help with syntax
setWatchdog(ModuleType.TYPEB, false);
}
} catch (StatusRuntimeException ex) {
// watchdog timed out - listener will
// update gui components
if (testforModuleType==ModuleType.TYPEA) {
// please help with syntax
setWatchdog(ModuleType.TYPEA, true);
} else {
// please help with syntax
setWatchdog(ModuleType.TYPEB, true);
}
}
});
} catch (InterruptedException ex) {}
}
updateMessage("Cancelled");
return null;
}
};
}
}
我使用这个类的方法是在JavaFX控制器类中,我在其中添加一个监听器,根据相关的布尔标志是真还是假来填充java gui元素。
答案 0 :(得分:1)
通常只有readonly map属性用于这种行为,即只有一个getter的ObservableMap
字段。只修改了地图的内容;分配初始地图后,不会为该字段分配新地图。
private final ObservableMap<ModuleType, Boolean> watchdog;
public ObservableMap<ModuleType, Boolean> getWatchdog() {
return watchdog;
}
地图本身的修改方式与修改java.util.Map
的方式相同,例如在这种情况下使用put
方法。可以观察到变化,例如使用MapChangeListener
或Bindings.valueAt
。
此外EnumMap
可用作Map
的支持ObservableMap
,但要执行此操作,需要使用observableMap
方法代替observableHashMap
方法
以下示例根据ObservableMap
中的值随机选择/取消选择2个复选框的值。
private CheckBox checkBoxA;
private CheckBox checkBoxB;
private ObservableMap<ModuleType, Boolean> map;
@Override
public void start(Stage primaryStage) {
checkBoxA = new CheckBox("type A");
checkBoxB = new CheckBox("type B");
map = FXCollections.observableMap(new EnumMap<>(ModuleType.class));
initMapListeners();
Thread t = new Thread(() -> {
Random random = new Random();
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
boolean b1 = random.nextBoolean();
boolean b2 = random.nextBoolean();
Platform.runLater(() -> {
map.put(ModuleType.TYPEA, b1);
map.put(ModuleType.TYPEB, b2);
});
}
});
t.setDaemon(true);
t.start();
Scene scene = new Scene(new VBox(10, checkBoxA, checkBoxB));
primaryStage.setScene(scene);
primaryStage.show();
}
以下initMapListeners()
的实现都会根据地图值设置CheckBox.selected
状态。
private void initMapListeners() {
checkBoxA.selectedProperty().bind(Bindings.valueAt(map, ModuleType.TYPEA));
checkBoxB.selectedProperty().bind(Bindings.valueAt(map, ModuleType.TYPEB));
}
private void initMapListeners() {
map.addListener((MapChangeListener.Change<? extends ModuleType, ? extends Boolean> change) -> {
if (change.wasAdded()) {
if (change.getKey() == ModuleType.TYPEA) {
checkBoxA.setSelected(change.getValueAdded());
} else if (change.getKey() == ModuleType.TYPEB) {
checkBoxB.setSelected(change.getValueAdded());
}
}
});
}