我需要向JavaFX服务类中添加一个SimpleMapProperty,但是我不确定是否使用了正确的方法来使用正确的语法。请注意,我并不是想使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控制器类中,在该类中,添加一个侦听器,该侦听器根据关联的布尔标志是true还是false来填充java gui元素。
最佳答案
通常,只读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());
}
}
});
}
关于java - 在可观察的SimpleMapProperty中包装EnumMap,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38834966/