【问题标题】:Change JavaFX style class based on model state根据模型状态更改 JavaFX 样式类
【发布时间】:2016-07-05 19:39:21
【问题描述】:

我有一个带有多个圆形的 JavaFX FXML 场景。每个圆圈代表一个灯泡。灯泡在具有特定 JavaFX CSS 类时打开,例如“lightOn”,否则关闭。 CSS 定义了圆的外观,这样当它有“lightOn”类时它看起来是闪亮的,当它没有类时它会变暗。

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

如何将视图的单个“灯泡”的样式类与表示其状态的模型的布尔字段联系起来? IE。当布尔值改变时,样式类必须更新。

(不需要样式类通过某种属性绑定自动更新——不过,这也可以。如果视图将被更新,例如,通过控制器实例更新就足够了它会定期轮询模型。)

【问题讨论】:

    标签: javafx


    【解决方案1】:

    您可以为此使用基于CSS based psuedo-class 的属性。

    如果你愿意,你可以将 CSS psuedo-class 支持的属性绑定到模型对象的属性上,这样当你更新模型时,关联视图的 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");
        }
    }
    

    【讨论】:

    • 我花了一段时间来消化您的解决方案。在很多方面真的很棒。我特别喜欢将圆圈变成自定义的“灯泡”控件。这使得他们在视图中的角色比简单的“圆圈”更加清晰。
    猜你喜欢
    • 1970-01-01
    • 2014-08-30
    • 2021-03-27
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 2020-10-08
    • 1970-01-01
    相关资源
    最近更新 更多