在可观察的 SimpleMapProperty 中包装 EnumMap
Wrapping an EnumMap in a observable SimpleMapProperty
I need to add a SimpleMapProperty to a JavaFX service class, but I am not sure of the correct syntax of if I am using the correct approach. Note that I am not trying to make the JavaFX service appear like a Java Bean, I just need to know how to listen for updates to an EnumMap from a enum ModuleType (that can be TYPEA or TYPEB) and an associated Boolean flag. Essentially, this can be thought of as a pair of watchdog timers wrapped in a single EnumMap.
I am having trouble understanding how to add the underlying EnumMap entries (there should be 2 - one for each ModuleType described above).
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;
}
};
}
}
The way I use this class is in the JavaFX controller class where I add a listener that populates java gui elements depending on whether the associated Boolean flag is true or false.
通常只读映射 属性 用于此类行为,即只有 getter 的 ObservableMap
字段。只修改地图的内容;初始地图分配后,没有新地图分配给字段。
private final ObservableMap<ModuleType, Boolean> watchdog;
public ObservableMap<ModuleType, Boolean> getWatchdog() {
return watchdog;
}
地图本身的修改方式与 java.util.Map
的修改方式相同,例如在这种情况下使用 put
方法。可以观察到变化,例如使用 MapChangeListener
或 Bindings.valueAt
.
此外,EnumMap
可用作 ObservableMap
的支持 Map
,但要做到这一点,需要使用 observableMap
方法而不是 [=23] =]方法。
以下示例根据 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());
}
}
});
}
I need to add a SimpleMapProperty to a JavaFX service class, but I am not sure of the correct syntax of if I am using the correct approach. Note that I am not trying to make the JavaFX service appear like a Java Bean, I just need to know how to listen for updates to an EnumMap from a enum ModuleType (that can be TYPEA or TYPEB) and an associated Boolean flag. Essentially, this can be thought of as a pair of watchdog timers wrapped in a single EnumMap.
I am having trouble understanding how to add the underlying EnumMap entries (there should be 2 - one for each ModuleType described above).
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;
}
};
}
}
The way I use this class is in the JavaFX controller class where I add a listener that populates java gui elements depending on whether the associated Boolean flag is true or false.
通常只读映射 属性 用于此类行为,即只有 getter 的 ObservableMap
字段。只修改地图的内容;初始地图分配后,没有新地图分配给字段。
private final ObservableMap<ModuleType, Boolean> watchdog;
public ObservableMap<ModuleType, Boolean> getWatchdog() {
return watchdog;
}
地图本身的修改方式与 java.util.Map
的修改方式相同,例如在这种情况下使用 put
方法。可以观察到变化,例如使用 MapChangeListener
或 Bindings.valueAt
.
此外,EnumMap
可用作 ObservableMap
的支持 Map
,但要做到这一点,需要使用 observableMap
方法而不是 [=23] =]方法。
以下示例根据 ObservableMap
.
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());
}
}
});
}