当前位置: 首页 > 知识库问答 >
问题:

JavaFX绑定设置器约定

巫欣荣
2023-03-14

我知道Java和C#,但属性绑定我只知道C#MVVM。我试图理解JavaFX中的属性绑定,使用属性值的自定义getter和setter(就像在C#中一样)。

我创建了以下类:

public class ViewModel {

    private StringProperty name;

    public ViewModel() {
        name = new SimpleStringProperty();
    }

    public final String getName() {
        return name.get();
    }

    public final void setName(String name) {
        this.name.set(name);
    }

    public StringProperty getNameProperty() {
        return name;
    }
}

public class Controller implements Initializable {

    @FXML
    private TextField nameField;

    private final ViewModel viewModel;

    public Controller() {
        viewModel = new ViewModel();
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        Bindings.bindBidirectional(nameField.textProperty(),
                viewModel.getNameProperty());
    }
}

我的印象是,如果我遵循推荐的JavaBean/JavaFX命名约定,那么绑定系统将足够聪明地使用反射(?)并为该属性使用自定义getter/setter。但是我的视图模型getter/setter从来没有使用过。

name = new SimpleStringProperty() {
    @Override public void set(String value) {
        // do something...
        super.set(value);
    }
};

在C#中,这很简单,我只是在setter中设置一个谓词。我可以通过设置其他属性来推动表单/向导的进程。

public String Property {
    get { return _property; }
    set { 
        if(SomePredicate(value)) {
            _property = value;
            _nextButtonCommand.canExecute() = true;
            // notify...
        }
    }
}

共有1个答案

轩辕实
2023-03-14
public class ViewModel {

    private StringProperty name;

    public ViewModel() {
        // parameters are owning bean, property name, and initial value, 
        // and are optional for the property convention
        name = new SimpleStringProperty(this, "name", "");
    }

    public final String getName() {
        return name.get();
    }

    public final void setName(String name) {
        this.name.set(name);
    }

    // Note this method name:
    public final StringProperty nameProperty() {
        return name;
    }
}
public class ViewModel {
    private StringProperty name = new SimpleStringProperty(this, "name");
    // usual JavaFX Property methods...
}
Predicate<String> predicate = ... ;
BooleanBinding canExecute = Bindings.createBooleanBinding(() -> 
    predicate.test(viewModel.getName()),
    viewModel.nameProperty());
Button nextButton = new Button("Next");
nextButton.disableProperty().bind(canExecute.not());
ObjectProperty<Predicate<String>> predicate = new SimpleObjectProperty<>(s -> true);
BooleanBinding canExecute = Bindings.createBooleanBinding(() -> 
    predicate.get().test(viewModel.getName()),
    predicate, viewModel.nameProperty());

通知

可以用属性注册InvalidationListenerChangeListenerAddListener(InvalidationListener)方法继承自Observable,并指示上次观察到的值可能不再有效。这允许“惰性计算”可观察项,只在请求新值时计算新值。AddListener(ChangeListener)方法继承自ObservableValue,后者(如其名称所示)是显式包装值的可观察性。注册ChangeListener会强制快速计算,因为监听器会收到新值的通知。虽然API为高性能实现提供了大量的灵活性,但对于我的口味来说,它的粒度有点太细了。

因此,在您的测试应用程序中,您可以

viewModel.nameProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> obs, String oldValue, String newValue) {
        System.out.println("Name changed from "+oldValue+" to "+newValue);
    }
});
viewModel.nameProperty().addListener((obs, oldName, newName) -> 
    System.out.println("Name changed from "+oldValue+" to "+newValue));
IntegerProperty x = new SimpleIntegerProperty(2);
IntegerProperty y = new SimpleIntegerProperty(3);
ObservableNumberValue sum = x.add(y);

sum.addListener(obs -> System.out.println("Invalidated")); // invalidation listener
x.set(3);
y.set(5);
sum.addListener((obs, oldSum, newSum) -> System.out.println("Changed"));
 类似资料:
  • 主要内容:绑定选项,双向绑定,高级别绑定,低级别绑定,UI控件和域模型之间的绑定JavaFX绑定同步两个值:当依赖变量更改时,其他变量更改。 要将属性绑定到另一个属性,请调用bind()方法,该方法在一个方向绑定值。 例如,当属性A绑定到属性B时,属性B的更改将更新属性A,但不可以反过来。 绑定选项 JavaFX提供了许多绑定选项,以便在域对象和GUI控件中的属性之间进行同步。 我们可以在JavaFX的Properties API中使用以下三种绑定策略: Java Bean上

  • 下面是我的代码:

  • 我在JavaFX的小游戏中工作。我有一个管理音乐的实用类:

  • 我有一个和一个,在hBox中有三个,一个包含文本,另一个包含表中两列的总和。我想为HBox设置一个动态的间距,使两个标签正好在它们所属的表中的两列下方对齐。是否有可能将的间距绑定到列的位置。我也接受任何其他将标签固定在相应列下方的解决方案。下面是一个显示我想要的图像:

  • 我有一个函数,有一系列约束。当然,这些约束必须出现在使用的函数的签名中,所以我试图将约束包装在类型同义词。例如, 会成为 如果所有类型都公开,这将非常有效。但是,我使用函数依赖来生成约束列表中的一些类型,这些类型不会出现在的签名中。例如: GHC不接受,因为在LHS上没有绑定。我也不能使用,因为不在