この質問では、ラッピングオブジェクトを変更し、変更された更新を送信しないことで、プロパティが変更されるという問題に対処する方法を示しました。解決策はReactFXを使用していました:
class Cell {
private final ObjectProperty<Shape> shape = new SimpleObjectProperty<>(new Shape());
// all getters and setterts
public static class Shape {
private final IntegerProperty size = new SimpleIntegerProperty(0);
// all getters and setterts
}
public static void main(String[] args) {
Var<Number> sizeVar = Val.selectVar(cell.shapeProperty(), Shape::sizeProperty);
sizeVar.addListener(
(obs, oldSize, newSize) -> System.out.println("Size changed from "+oldSize+" to "+newSize));
}
したがって、shape
プロパティ自体が変更されると、変更もトリガーされsize
ます (新しい形状が同じサイズでない限り)。しかし、カスタムバインディングを使用してプロパティにバインドしたいのですが、以下で説明する問題があります。
私のデータクラスは次のとおりです。
class Cell {
private final ObjectProperty<Shape> shape = new SimpleObjectProperty<>();
public final ObjectProperty<Shape> shapeProperty() { return shape; }
public final Shape getShape() { return shapeProperty().get(); }
public final void setShape(Shape shape) { shapeProperty().set(shape); }
// other properties
}
class Shape {
private final IntegerProperty size = new SimpleIntegerProperty();
public final IntegerProperty sizeProperty() { return size; }
public final int getSize() { return size.get(); }
public final void setSize(int size) { sizeProperty().set(size); }
// other properties
}
そして、それらのプロパティを GUI プロパティにバインドして、それらの GUI 表現を作成したいと考えています。私はこのようにします:
class CellRepresentation extends Group {
private final Cell cell;
CellRepresentation(Cell cell) {
this.cell = cell;
getChildren().add(new ShapeRepresentation() /*, other representations of things in the cell*/);
}
private class ShapeRepresentation extends Cylinder {
ObjectProperty<Shape> shape;
private ShapeRepresentation() {
super(100, 100);
shape = new SimpleObjectProperty<Shape>(cell.getShape());
shape.bind(cell.shapeProperty());
Var<Number> sizeVar = Val.selectVar(cell.shapeProperty(), Shape::sizeProperty);
// THIS WILL WORK
materialProperty().bind(Bindings.createObjectBinding(() -> {
if (shape.get() == null)
return new PhongMaterial(Color.TRANSPARENT);
return new PhongMaterial(Color.RED);
}, sizeVar));
// THIS WILL NOT WORK
materialProperty().bind(sizeVar.map(n -> {
if (shape.get() == null)
return new PhongMaterial(Color.TRANSPARENT);
return new PhongMaterial(Color.RED);
}));
}
}
// the other representations of things in the cell
}
以下のコードを実行すると、バインドの最初のオプションによって透明な円柱が作成されます。2 番目のオプションは、白 (既定の色) の円柱を作成します。なぜこれが起こるのかわかりません。
public class Example extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Cell cell = new Cell();
CellRepresentation cellRep = new CellRepresentation(cell);
Group group = new Group(cellRep);
Scene scene = new Scene(group, 200, 200, Color.AQUA);
stage.setScene(scene);
stage.show();
}
}
また、バインディングを使用してデータ クラスの表現を作成する方法が適切でない場合は、設計に関する提案も受け付けています。