根据模型状态更改JavaFX样式类 [英] Change JavaFX style class based on model state

查看:204
本文介绍了根据模型状态更改JavaFX样式类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有多个圆形的JavaFX FXML场景。每个圆圈代表一个灯泡。当灯泡具有某个JavaFX CSS类时,它会打开,例如lightOn,否则它会关闭。 CSS定义圆圈的外观,使其在具有lightOn类时显得闪亮,并在没有类时变暗。



我也有一个平原Java对象作为模型,包含布尔值的集合。每个布尔值属于视图的单个灯泡,并指示灯是打开还是关闭。



如何连接单个灯泡的样式类代表其状态的模型的布尔字段的视图?即样式类必须在布尔值更改时更新。



(样式类不需要通过某种属性绑定自动更新 - 但是,如果视图会被更新,例如,定期轮询模型的控制器实例,那就足够了。)

解决方案

您可以使用基于属性的



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;

公共类LightArray扩展应用程序{
@Override
public void start(最后阶段阶段)抛出异常{
Bulb bulb1 = new Bulb();
Bulb bulb2 = new Bulb();
bulb2.setOn(true);

最终HBox布局=新HBox(10,bulb1,bulb2);
layout.setPadding(new Insets(10));
场景场景=新场景(布局);
scene.getStylesheets()。add(
this.getClass()。getResource(bulb.css)。toExternalForm()
);
stage.setScene(场景);
stage.show();
}

public static void main(String [] args){
launch(args);
}

静态私有类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(){
returnon;
}
};

private static final PseudoClass
ON_PSEUDO_CLASS = PseudoClass.getPseudoClass(on);
}
}


I have a JavaFX FXML scene with an number of circle shapes. Each circle represents a light bulb. A light bulb is turned on when it has a certain JavaFX CSS class, say "lightOn", otherwise it is off. The CSS defines the appearance of the circle so that it appear shining when it has the "lightOn" class, and dimmed when it has no class.

I also have a plain Java object as model which holds a collection of Boolean values. Each boolean value belongs to an individual light bulb of the view and indicates whether the light is on or off.

How can connect the style class of the individual "light bulbs" of the view to the Boolean field of the model which represents their state? I.e. the style class must update when the Boolean value changes.

(It is not required that the style class automatically updates through some kind of property binding---though, that would be OK also. It would be sufficient, if the view would be updated, for instance, by a controller instance which periodically polls the model.)

解决方案

You could use a property based CSS based psuedo-class for this.

If you want, you can bind the property which is backed by the CSS psuedo-class to a property of your model object, so when you update the model, the CSS pseudo-class of the associated view is automatically modified and the view updated as appropriate.

In the image below, each circle represents a bulb. Each bulb has an associated property which represents it's state (a BooleanProperty indicating whether the bulb is on or not). The invalidated() method of the property is used to trigger notifications of changes to an associated CSS pseudo-class state, which updates the style of the bulb depending upon whether the bulb is switched on or not.

As onProperty() is an exposed property of bulb, you can bind it to an appropriate boolean property of your model. This is a similar implementation in some ways to how other CSS pseudo-class backed controls in the JavaFX API work, such as check-boxes and toggle buttons.

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");
    }
}

这篇关于根据模型状态更改JavaFX样式类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆