根据模型状态更改JavaFX样式类

根据模型状态更改JavaFX样式类,javafx,Javafx,我有一个带有许多圆形的JavaFXML场景。每个圆圈代表一个灯泡。当一个灯泡有一个特定的JavaFXCSS类,比如说“lightOn”时,它是打开的,否则它是关闭的。CSS定义了圆的外观,这样当它有“lightOn”类时,它会发光,当它没有类时,它会变暗 我还有一个普通的Java对象作为模型,它包含一组布尔值。每个布尔值都属于视图的单个灯泡,并指示灯光是打开还是关闭 如何将视图中各个“灯泡”的样式类连接到表示其状态的模型布尔字段?即,当布尔值更改时,样式类必须更新 (不要求样式类通过某种类型的属

我有一个带有许多圆形的JavaFXML场景。每个圆圈代表一个灯泡。当一个灯泡有一个特定的JavaFXCSS类,比如说“lightOn”时,它是打开的,否则它是关闭的。CSS定义了圆的外观,这样当它有“lightOn”类时,它会发光,当它没有类时,它会变暗

我还有一个普通的Java对象作为模型,它包含一组布尔值。每个布尔值都属于视图的单个灯泡,并指示灯光是打开还是关闭

如何将视图中各个“灯泡”的样式类连接到表示其状态的模型布尔字段?即,当布尔值更改时,样式类必须更新


(不要求样式类通过某种类型的属性绑定自动更新,但也可以。如果视图可以更新,例如由定期轮询模型的控制器实例更新,就足够了。)

您可以使用基于属性的方法进行此操作

如果需要,可以将CSS psuedo类支持的属性绑定到模型对象的属性,以便在更新模型时,自动修改关联视图的CSS伪类,并根据需要更新视图

在下图中,每个圆代表一个灯泡。每个灯泡都有一个表示其状态的关联属性(指示灯泡是否打开的布尔属性)。属性的
invalidated()
方法用于触发关联CSS伪类状态的更改通知,该状态根据灯泡是否打开而更新灯泡的样式

由于
onProperty()
是灯泡的公开属性,因此可以将其绑定到模型的适当布尔属性。这在某些方面与JavaFXAPI中其他CSS伪类支持的控件(如复选框和切换按钮)的工作方式类似

bulb.css

LightArray.java


我花了一段时间才明白你的解决办法。这在很多方面都很好。我特别喜欢把圆圈变成定制的“灯泡”控件。这使得他们在视图中的角色比普通的“圆圈”更清晰。
.bulb {
    -fx-fill: lightslategray;
}

.bulb:on {
    -fx-fill: gold;
}
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");
    }
}