owned this note
owned this note
Published
Linked with GitHub
# Property
[JavaFX: Properties and Binding Tutorial](https://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm)
[抽象 javafx.beans.property.StringProperty](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/StringProperty.html)
[javafx.beans.property.SimpleStringProperty](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/SimpleStringProperty.html)
```java
java.lang.Object
javafx.beans.binding.StringExpression
javafx.beans.property.ReadOnlyStringProperty
javafx.beans.property.StringProperty
javafx.beans.property.StringPropertyBase
javafx.beans.property.SimpleStringProperty
```
[抽象javafx.beans.property.BooleanProperty](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/BooleanProperty.html)
[javafx.beans.property.SimpleBooleanProperty](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/SimpleBooleanProperty.html)
[抽象IntegerProperty](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/IntegerProperty.html)
[SimpleIntegerProperty](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/SimpleIntegerProperty.html)
[抽象DoubleProperty](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/DoubleProperty.html)
[SimpleDoubleProperty ](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/SimpleDoubleProperty.html)
[抽象ObjectProperty<T>](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/ObjectProperty.html)
[SimpleObjectProperty<T>](https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/SimpleObjectProperty.html)
<hr>
```java
StringProperty name=new SimpleStringProperty();
IntegerProperty id=new SimpleIntegerProperty();
DoubleProperty pct=new SimpleDoubleProperty();
SimpleObjectProperty<Date> hire_date= new SimpleObjectProperty<>();
```
```java
public StringProperty nameProperty() {
return name;
}
public IntegerProperty idProperty(){
return id;
}
public DoubleProperty pctProperty(){
return pct;
}
public SimpleObjectProperty<Date> hireDateProperty(){
return hire_date;
}
public String getName () {
return name.get();
}
public void setName(String name){
this.name.set(name);
}
public void setId(int id1){
this.id.set(id1);
}
public void getId(){
this.id.get();
}
public double getPct() {
return pct.get();
}
public void setPct(double pct){
this.pct.set(pct);
}
public Object getHireDate(){
return hire_date.get();
}
public void setHireDate(Date hireDate){
this.hire_date.set(hireDate);
}
```
https://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm
JavaBeans組件體系結構通過定義一些簡單的命名約定來解決此問題,這些約定使項目之間的一致性。在JavaBeans編程中,這些方法的完整簽名將是: public void setFirstName(String name), public String getFirstName(), public void setLastName(String name), 和 public String getLastName()。對於人類程序員和編輯工具(例如NetBeans IDE),都可以輕鬆識別這種命名模式。在JavaBeans術語中 Person 據說對象包含 firstName 和 lastName 屬性。
[Java教程的JavaBeans課程](https://docs.oracle.com/javase/tutorial/javabeans/)
```java=
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
class Bill {
// Define a variable to store the property
private DoubleProperty amountDue = new SimpleDoubleProperty();
// Define a getter for the property's value
public final double getAmountDue(){return amountDue.get();}
// Define a setter for the property's value
public final void setAmountDue(double value){amountDue.set(value);}
// Define a getter for the property itself
public DoubleProperty amountDueProperty() {return amountDue;}
}
```
類標記為 private 從外部世界封裝它。這是Java和JavaBeans應用程序開發中的標準做法。
a new wrapper class that encapsulates a Java primitive and adds some extra functionality (the classes under javafx.beans.property all contain built-in support for observability and binding as part of their design
整數或浮點數..新的封裝成IntegerProperty或DoubleProperty
getter
setter
* the amountDueProperty() method defines the property getter.
使用JavaFX構建GUI應用程序時,您會注意到API中的某些類已經實現了屬性。例如 javafx.scene.shape.Rectangle class包含 arcHeight, arcWidth, height, width, x, 和 y。
When building GUI applications with JavaFX, you will notice that certain classes in the API already implement properties. For example, the javafx.scene.shape.Rectangle class contains properties for arcHeight, arcWidth, height, width, x, and y.
You can also add a change listener to be notified when the property's value has changed 您還可以添加更改偵聽器,以在屬性值更改時通知它,如圖所示
```java=
import javafx.beans.value.ObservableValue;
import javafx.beans.value.ChangeListener;
public class Main {
public static void main(String[] args) {
Bill electricBill = new Bill();
electricBill.amountDueProperty().addListener(new ChangeListener(){
@Override public void changed(ObservableValue o,Object oldVal,
Object newVal){
System.out.println("Electric bill has changed!");
}
});
electricBill.setAmountDue(100.00);
}
}
```
There are three variables involved: num1 (a dependency), num2 (a dependency), and sum (the binding). The dependency types are both IntegerProperty, and the binding itself is NumberBinding
```java=
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.binding.NumberBinding;
import javafx.beans.binding.Bindings;
public class Main {
public static void main(String[] args) {
IntegerProperty num1 = new SimpleIntegerProperty(1);
IntegerProperty num2 = new SimpleIntegerProperty(2);
NumberBinding sum = num1.add(num2);
//可使用Bindings
NumberBinding sum2 = Bindings.add(num1,num2);
System.out.println(sum.getValue());
num1.set(2);
System.out.println(sum.getValue());
}
}
```
```java=
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.binding.NumberBinding;
import javafx.beans.binding.Bindings;
public class Main {
public static void main(String[] args) {
IntegerProperty num1 = new SimpleIntegerProperty(1);
IntegerProperty num2 = new SimpleIntegerProperty(2);
IntegerProperty num3 = new SimpleIntegerProperty(3);
IntegerProperty num4 = new SimpleIntegerProperty(4);
NumberBinding total =
Bindings.add(num1.multiply(num2),num3.multiply(num4));
System.out.println(total.getValue());
num1.setValue(2);
System.err.println(total.getValue());
}
}
```
高級API可以在定義算術運算時混合類型。結果的類型由與Java編程語言相同的規則定義:
* If one of the operands is a double, the result is a double.
如果其中一個是 double, 結果是 double。
* If not and one of the operands is a float, the result is a float.
如果不是,則其中一個是 float, 結果是 float。
* If not and one of the operands is a long, the result is a long.
如果不是,則其中一個是 long, 結果是 long。
* The result is an integer otherwise.
結果是整數,否則。
探索可觀察,可觀察值,無效偵聽器和ChangeListener
Exploring Observable, ObservableValue, InvalidationListener, and ChangeListener
The binding API defines a set of interfaces that enable objects to be notified when a value change or invalidation takes place. 綁定API定義了一組接口,這些接口使值更改或無效時可以通知對象。
The Observable and ObservableValue interfaces fire the change notifications,and the InvalidationListener and ChangeListener interfaces receive them.
The Observable 和 ObservableValue 接口發出更改通知,並且
InvalidationListener 和 ChangeListener 接口接收它們。
兩者之間的區別是 ObservableValue 包裝一個值並將其更改觸發到任何已註冊 ChangeListener, 而 Observable ( 不 包裝一個值)會將其更改觸發到任何已註冊 InvalidationListener。
The difference between the two is that ObservableValue wraps a value and fires its changes to any registered ChangeListener, whereas Observable (which does not wrap a value) fires its changes to any registered InvalidationListener.
JavaFX綁定和屬性實現都支持懶惰的評估,這意味著當發生更改時,不會立即重新計算該值。如果隨後要求該值,則稍後會進行重新計算。
The JavaFX binding and property implementations all support lazy evaluation, which means that when a change occurs, the value is not immediately recomputed. Recomputation happens later, if and when the value is subsequently requested.
在 示例1-6, 第一次檢測到其依賴關係之一的變化時,總帳單( a綁定)將被標記為無效。但是,僅當再次實際請求總和時,綁定對象才會重新計算自身。
示例1-6使用InvalidationListener, Using an InvalidationListener
```java=
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.binding.NumberBinding;
import javafx.beans.binding.Bindings;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
class Bill {
// Define the property 定義屬性
private DoubleProperty amountDue = new SimpleDoubleProperty();
// Define a getter for the property's value
// 為財產的價值定義 獲取者
public final double getAmountDue(){return amountDue.get();}
// Define a setter for the property's value
//為屬性的值定義一個設置器
public final void setAmountDue(double value){amountDue.set(value);}
// Define a getter for the property itself
// 為屬性本身定義獲取者
public DoubleProperty amountDueProperty() {return amountDue;}
}
public class Main {
public static void main(String[] args) {
Bill bill1 = new Bill();
Bill bill2 = new Bill();
Bill bill3 = new Bill();
NumberBinding total =
Bindings.add(bill1.amountDueProperty().add(bill2.amountDueProperty()),
bill3.amountDueProperty());
total.addListener(new InvalidationListener() { //新無效Listener
@Override public void invalidated(Observable o) { //無效 可觀察o
System.out.println("The binding is now invalid."); //綁定現在無效
}
});
// 首次調用使綁定無效
// First call makes the binding invalid
bill1.setAmountDue(200.00);
// 綁定現在無效
// The binding is now invalid
bill2.setAmountDue(100.00);
bill3.setAmountDue(75.00);
//使綁定有效...
// Make the binding valid...
System.out.println(total.getValue());
//使無效...
// Make invalid...
bill3.setAmountDue(150.00);
// Make valid..生效
System.out.println(total.getValue());
}
}
```
By changing the value of a single bill, the binding becomes invalid, and the invalidation listener will fire. But if the binding is already invalid, the invalidation listener will not fire again, even if another bill changes.
(In Example 1-6, invoking total.getValue() moves the binding from invalid to valid.) We know this because a subsequent change to any bill in the dependency list will cause the invalidation listener to fire again. This would not happen if the binding was still invalid.
通過更改單個帳單的值,綁定將變為無效,並且無效聽眾將觸發。
但是,如果綁定已經無效,則即使其他帳單更改,無效聽眾也不會再次觸發。
(在 示例1-6, 調用 total.getValue() 將綁定從無效移動到有效。) 我們之所以知道這一點,是因為隨後對依賴項列表中的任何帳單進行的更改將導致無效聽眾再次解僱。如果綁定仍然無效,則不會發生這種情況。
Note that registering a ChangeListener will enforce eager computation, even if the implementation of the ObservableValue supports lazy evaluation. For a lazily evaluated value, it is not possible to know if an invalid value really has changed until it is recomputed. For this reason, generating change events requires eager evaluation, while invalidation events can be generated for both eager and lazy implementations.
請注意註冊 ChangeListener 即使執行 ObservableValue 支持懶惰的評估。對於懶惰的評估值,在重新計算之前不可能知道無效值是否真的已更改。因此,生成更改事件需要急切的評估,而對於急切和懶惰的實現都可以生成無效事件。
使用低級綁定API Using the Low-Level Binding API
如果高級API不足以滿足您的要求,則可以隨時使用低級API。低級API適用於需要比高級API更大的靈活性(或更好的性能)的開發人員。
示例1-7 顯示使用低級API的基本示例。
使用低級API的示例1-7
```java=
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.binding.DoubleBinding;
public class Main {
public static void main(String[] args) {
final DoubleProperty a = new SimpleDoubleProperty(1);
final DoubleProperty b = new SimpleDoubleProperty(2);
final DoubleProperty c = new SimpleDoubleProperty(3);
final DoubleProperty d = new SimpleDoubleProperty(4);
DoubleBinding db = new DoubleBinding() {
{
super.bind(a, b, c, d);
}
@Override
protected double computeValue() {
return (a.get() * b.get()) + (c.get() * d.get());
}
};
System.out.println(db.get());
b.set(3);
System.out.println(db.get());
}
}
```
使用低級API涉及擴展綁定類之一並覆蓋其 computeValue() 返回綁定的當前值的方法。示例1-7 使用以下自定義子類執行此操作 DoubleBinding。調用 super.bind() 將依賴項傳遞給 DoubleBinding 這樣就可以保留默認的失效行為。通常,您無需檢查綁定是否無效;基本類為您提供了此行為。
您現在知道足夠的信息以開始使用低級API。
https://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm
<hr>