Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java StyleableProperty:如何在运行时以编程方式更改值?_Java_Css_Javafx - Fatal编程技术网

Java StyleableProperty:如何在运行时以编程方式更改值?

Java StyleableProperty:如何在运行时以编程方式更改值?,java,css,javafx,Java,Css,Javafx,我的用例: 控件上的自定义属性,应通过css进行配置 该属性在运行时必须是可更改的 对于控件的给定实例,在重新应用css时不得恢复编程更改 定制看起来是实现需求的完美匹配。下面是一个实现的示例(取自的javadoc类,未做任何更改) 除了最后一个要求外,一切正常:在applyCss上,重新应用样式表中的默认值。复制: 运行该示例,请注意MyButton的初始“selected”状态(复选框“selected is bound it”)为true 单击custom按钮,注意“selected

我的用例:

  • 控件上的自定义属性,应通过css进行配置
  • 该属性在运行时必须是可更改的
  • 对于控件的给定实例,在重新应用css时不得恢复编程更改
定制看起来是实现需求的完美匹配。下面是一个实现的示例(取自的javadoc类,未做任何更改)

除了最后一个要求外,一切正常:在applyCss上,重新应用样式表中的默认值。复制:

  • 运行该示例,请注意MyButton的初始“selected”状态(复选框“selected is bound it”)为true
  • 单击custom按钮,注意“selected”不会更改为false(尽管actionHandler会更改它)
  • 单击第二个(“切换”)按钮,请注意,自定义按钮的选定状态将更改为false
  • 将鼠标悬停在“自定义”按钮上,请注意,选定的状态会返回到true
返回true(通过样式设置的值)的原因可以追溯到状态更改时发生的applyCss。。。这是可以理解的,在大多数情况下可能是正确的,但在我的背景下不是这样

因此,问题是:

  • 我使用StyleableProperty的方法正确吗
  • 如果是这样,如何调整,使其在发生手动更改后不会重新应用
  • 如果没有,还有什么办法
  • 或者可能问了一个完全错误的问题:可能通过css设置的属性不应该被代码(永久)更改
例如:

public class StyleableButtonDriver extends Application {

    /**
     * example code from class doc of StyleablePropertyFactory.
     */
    private static class MyButton extends Button {

        private static final StyleablePropertyFactory<MyButton> FACTORY 
            = new StyleablePropertyFactory<>(Button.getClassCssMetaData());

        MyButton(String labelText) {
            super(labelText);
            getStyleClass().add("my-button");
            setStyle("-my-selected: true");
        }

        // Typical JavaFX property implementation
        public ObservableValue<Boolean> selectedProperty() { return (ObservableValue<Boolean>)selected; }
        public final boolean isSelected() { return selected.getValue(); }
        public final void setSelected(boolean isSelected) { selected.setValue(isSelected); }

        // StyleableProperty implementation reduced to one line
        private final StyleableProperty<Boolean> selected =
             FACTORY.createStyleableBooleanProperty(
                    this, "selected", "-my-selected", s -> s.selected);

        @Override
        public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
            return FACTORY.getCssMetaData();
        }

        public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
            return FACTORY.getCssMetaData();
        }

    }
    private Parent createContent() {
        MyButton button = new MyButton("styleable button");
        button.setOnAction(e ->  {
            // does not work: reset on applyCss
            boolean isSelected = button.isSelected();
            button.setSelected(!isSelected);
        });

        CheckBox box = new CheckBox("button selected");
        box.selectedProperty().bind(button.selectedProperty());

        Button toggle = new Button("toggle button");
        toggle.setOnAction(e -> {
            boolean isSelected = button.isSelected();
            button.setSelected(!isSelected);
        });


        BorderPane content = new BorderPane(button);
        content.setBottom(new HBox(10, box, toggle));
        return content;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent(), 300, 200));
        //same behavior as setting the style directly
//        URL uri = getClass().getResource("xstyleable.css");
//        stage.getScene().getStylesheets().add(uri.toExternalForm());
        // not useful: would have to override all
//        Application.setUserAgentStylesheet(uri.toExternalForm());
        stage.setTitle(FXUtils.version());
        stage.show();
    }

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

    @SuppressWarnings("unused")
    private static final Logger LOG = Logger
            .getLogger(StyleableButtonDriver.class.getName());

}
公共类StyleableButtonDriver扩展应用程序{
/**
*StyleablePropertyFactory类文档中的示例代码。
*/
私有静态类MyButton扩展按钮{
私有静态最终StyleablePropertyFactory工厂
=新的StyleablePropertyFactory(Button.getClassCssMetaData());
MyButton(字符串标签文本){
超级(标签文本);
getStyleClass().add(“我的按钮”);
setStyle(“-my selected:true”);
}
//典型的JavaFX属性实现
public observeValue selectedProperty(){return(observeValue)selected;}
公共最终布尔值isSelected(){返回selected.getValue();}
公共最终void setSelected(布尔值isSelected){selected.setValue(isSelected);}
//StyleableProperty实现减少到一行
已选择私有最终StyleableProperty=
FACTORY.createStyleableBooleanProperty(
此选项为“已选择”,“我的已选择”,s->s已选择);
@凌驾
public List>getClassCssMetaData(){
return FACTORY.getCssMetaData();
}
}
私有父createContent(){
MyButton button=新建MyButton(“可样式化按钮”);
按钮。设置操作(e->{
//不工作:在applyCss上重置
布尔值isSelected=按钮。isSelected();
按钮.setSelected(!isSelected);
});
复选框=新复选框(“选中的按钮”);
box.selectedProperty().bind(button.selectedProperty());
按钮切换=新按钮(“切换按钮”);
切换设置动作(e->{
布尔值isSelected=按钮。isSelected();
按钮.setSelected(!isSelected);
});
边框窗格内容=新建边框窗格(按钮);
setBottom(新的HBox(10,框,切换));
返回内容;
}
@凌驾
public void start(Stage)引发异常{
stage.setScene(新场景(createContent(),300200));
//与直接设置样式的行为相同
//URL uri=getClass().getResource(“xstyleable.css”);
//stage.getScene().getStylesheets().add(uri.toExternalForm());
//不有用:必须覆盖所有
//setUserAgentStylesheet(uri.toExternalForm());
stage.setTitle(FXUtils.version());
stage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
@抑制警告(“未使用”)
专用静态最终记录器日志=记录器
.getLogger(StyleableButtonDriver.class.getName());
}

您的做法是正确的,但由于需要覆盖样式来源的默认优先级(用户代理样式表<编程指定节点.样式属性),因此无法使用
SyleablePropertyFactory
创建此属性。您需要创建一个
CssMetaData
对象,如果某个属性是通过编程指定的,则该对象将该属性指示为不可设置

private static class MyButton extends Button {

    private static final List<CssMetaData<? extends Styleable, ?>> CLASS_CSS_METADATA;
    private static final CssMetaData<MyButton, Boolean> SELECTED;

    static {
        SELECTED = new CssMetaData<MyButton, Boolean>("-my-selected", StyleConverter.getBooleanConverter()) {

            @Override
            public boolean isSettable(MyButton styleable) {
                // not setable, if bound or set by user
                return styleable.selected.getStyleOrigin() != StyleOrigin.USER  && !styleable.selected.isBound();
            }

            @Override
            public StyleableProperty<Boolean> getStyleableProperty(MyButton styleable) {
                return styleable.selected;
            }

        };

        // copy list of button css metadata to list and add new metadata object
        List<CssMetaData<? extends Styleable, ?>> buttonData = Button.getClassCssMetaData();
        List<CssMetaData<? extends Styleable, ?>> mybuttonData = new ArrayList<>(buttonData.size()+1);
        mybuttonData.addAll(buttonData);
        mybuttonData.add(SELECTED);
        CLASS_CSS_METADATA = Collections.unmodifiableList(mybuttonData);
    }

    MyButton(String labelText) {
        super(labelText);
        getStyleClass().add("my-button");
        setStyle("-my-selected: true");
    }

    // Typical JavaFX property implementation
    public ObservableValue<Boolean> selectedProperty() { return selected; }
    public final boolean isSelected() { return selected.get(); }
    public final void setSelected(boolean isSelected) { selected.set(isSelected); }

    // StyleableProperty implementation reduced to one line
    private final SimpleStyleableBooleanProperty selected = new SimpleStyleableBooleanProperty(SELECTED, this, "selected");

    @Override
    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
        return CLASS_CSS_METADATA;
    }

    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
        return CLASS_CSS_METADATA;
    }

}
私有静态类MyButton扩展按钮{
私有静态最终列表>buttonData=Button.getClassCssMetaData();
列表>getControlCssMetaData(){
返回类\u CSS\u元数据;
}

公共静态列表看起来很有希望-明天将尝试并返回,谢谢:-)