我有一个带有多个圆形的JavaFX FXML场景。每个圆圈代表一个灯泡。当灯泡具有某个JavaFX CSS类时,它会打开,例如“lightOn”,否则它会关闭。 CSS定义圆的外观,使其在具有“lightOn”类时显得闪亮,在没有类时显得暗淡。
我还有一个普通的Java对象作为模型,它包含一组布尔值。每个布尔值属于视图的单个灯泡,并指示灯是打开还是关闭。
如何将视图的各个“灯泡”的样式类连接到代表其状态的模型的布尔字段?即当布尔值改变时,样式类必须更新。
(样式类不需要通过某种属性绑定自动更新 - 但是,也可以。如果视图将被更新,例如,由控制器实例更新就足够了。定期轮询模型。)
答案 0 :(得分:1)
您可以使用基于CSS based psuedo-class的属性。
如果需要,可以将CSS伪造类支持的属性绑定到模型对象的属性,因此在更新模型时,会自动修改关联视图的CSS伪类,并且视图已更新。
在下图中,每个圆圈代表一个灯泡。每个灯泡都有一个相关的属性,代表它的状态(一个BooleanProperty指示灯泡是否打开)。该属性的invalidated()
方法用于触发相关CSS伪类状态更改的通知,该状态根据灯泡是否打开更新灯泡的样式。
由于onProperty()
是灯泡的外露属性,您可以将其绑定到模型的适当布尔属性。这在某些方面类似于JavaFX API中其他CSS伪类支持控件的工作方式,例如复选框和切换按钮。
bulb.css
.bulb {
-fx-fill: lightslategray;
}
.bulb:on {
-fx-fill: gold;
}
LightArray.java
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.css.PseudoClass;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class LightArray extends Application {
@Override
public void start(final Stage stage) throws Exception {
Bulb bulb1 = new Bulb();
Bulb bulb2 = new Bulb();
bulb2.setOn(true);
final HBox layout = new HBox(10, bulb1, bulb2);
layout.setPadding(new Insets(10));
Scene scene = new Scene(layout);
scene.getStylesheets().add(
this.getClass().getResource("bulb.css").toExternalForm()
);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
static private class Bulb extends Circle {
Bulb() {
super(30);
getStyleClass().add("bulb");
}
public void setOn(boolean on) {
this.on.set(on);
}
public boolean isOn() {
return on.get();
}
public BooleanProperty onProperty() {
return on;
}
public BooleanProperty on =
new BooleanPropertyBase(false) {
@Override protected void invalidated() {
pseudoClassStateChanged(ON_PSEUDO_CLASS, get());
}
@Override public Object getBean() {
return Bulb.this;
}
@Override public String getName() {
return "on";
}
};
private static final PseudoClass
ON_PSEUDO_CLASS = PseudoClass.getPseudoClass("on");
}
}