JavaFX屬性


JavaFX屬性儲存控制元件的內部狀態,並允許我們監聽來自JavaFX UI控制元件的狀態更改。JavaFX屬性可以彼此系結。系結行為允許屬性根據來自另一個屬性的更改值來同步其值。

JavaFX屬性的型別

有兩種型別的JavaFX屬性:

  • 讀寫(Read/Writable)
  • 唯讀(Read-Only)

JavaFX的屬性包含實際值,並提供更改支援,無效支援和系結功能。所有JavaFX屬性類都位於javafx.beans.property.*包名稱空間中。
下面的列表是常用的屬性類。

  • javafx.beans.property.SimpleBooleanProperty
  • javafx.beans.property.ReadOnlyBooleanWrapper
  • javafx.beans.property.SimpleintegerProperty
  • javafx.beans.property.ReadOnlyintegerWrapper
  • javafx.beans.property.SimpleDoubleProperty
  • javafx.beans.property.ReadOnlyDoubleWrapper
  • javafx.beans.property.SimpleStringProperty
  • javafx.beans.property.ReadOnlyStringWrapper

Simple的屬性是讀/寫屬性類。擁有ReadOnly的屬性是唯讀屬性。

讀/可寫屬性

讀/寫屬性是可以讀取和修改的屬性值。例如,SimpleStringProperty類建立一個字串屬性,該屬性對包裝的字串值是可讀寫的。
以下程式碼演示了SimpleStringProperty類的一個範例,並通過set()方法修改該屬性。

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Main{
  public static void main(String[] args) {
    StringProperty password  = new SimpleStringProperty("tw511.com");
    password.set("example.com");
    System.out.println("Modified StringProperty "  + password.get() );
  }
}

上面的程式碼生成以下結果。

Modified StringProperty example.com

上面的程式碼宣告了型別為StringProperty的變數password,並分配給SimpleStringProperty類的範例。實際的值是字串「tw511.com」,它被傳遞到SimpleStringProperty類別建構函式中。

要讀取值,請呼叫get()方法或getValue()方法,該方法返回實際的包裝值。如果要修改這個值,請呼叫set()方法或setValue()並傳入一個字串值。

唯讀屬性

要建立唯讀屬性,請使用以ReadOnly作為字首的包裝類。建立唯讀屬性需要兩個步驟。

  1. 範例化唯讀包裝類
  2. 呼叫方法getReadOnlyProperty()返回一個真正的唯讀屬性物件
ReadOnlyStringWrapper userName = new ReadOnlyStringWrapper("tw511.com"); 
ReadOnlyStringProperty readOnlyUserName  = userName.getReadOnlyProperty();

JavaFX JavaBean

以下程式碼顯示了如何建立JavaFX JavaBean。當構建基於Swing的應用程式時,我們使用gettersetter建立JavaBean

然後我們必須通過Swing模型類在UI邏輯中獲取和設定資料。通過使用JavaFX屬性建立JavaFX JavaBean,JavaFX將執行資料系結,並完成域模型類和UI控制元件之間的資料交換作業。參考以下程式碼 -

import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

class User {
  private final static String USERNAME_PROP_NAME = "userName";
  private final ReadOnlyStringWrapper userName;
  private final static String PASSWORD_PROP_NAME = "password";
  private StringProperty password;

  public User() {
    userName = new ReadOnlyStringWrapper(this, USERNAME_PROP_NAME,"fake user");
    password = new SimpleStringProperty(this, PASSWORD_PROP_NAME, "");
  }
  public final String getUserName() {
    return userName.get();
  }

  public ReadOnlyStringProperty userNameProperty() {
    return userName.getReadOnlyProperty();
  }

  public final String getPassword() {
    return password.get();
  }

  public final void setPassword(String password) {
    this.password.set(password);
  }

  public StringProperty passwordProperty() {
    return password;
  }
}

屬性更改事件

屬性可以通知值更改的事件處理程式,以便在屬性更改時進行響應處理相關操作。JavaFX屬性物件包含一個addListener()方法,它接受兩種型別的功能介面:ChangeListenerinvalidationListener
所有JavaFX屬性都是實現了ObservableValueObservable介面,它們分別為ChangeListenerinvalidationListener提供了addListener()方法。

以下程式碼顯示如何建立ChangeListener來註冊到屬性。當屬性的值發生改變時,將呼叫change()方法。

import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;

public class Main {// copyright w  w w .Yi I b A I .COm 
  public static void main(String[] args) {
    SimpleIntegerProperty xProperty = new SimpleIntegerProperty(0);

    // Adding a change listener with anonymous inner class
    xProperty.addListener(new ChangeListener<Number>() {
      @Override
      public void changed(ObservableValue<? extends Number> ov, Number oldVal,
          Number newVal) {
        System.out.println("old value:"+oldVal);
        System.out.println("new value:"+newVal);
      }
    });

    // Adding a change listener with lambda expression
    xProperty.addListener((ObservableValue<? extends Number> ov, Number oldVal,
        Number newVal) -> {
          System.out.println("old value:"+oldVal);
          System.out.println("new value:"+newVal);
      });
  }
}

以下程式碼顯示了如何建立一個invalidationListener以向屬性註冊。隨著屬性的值改變,將呼叫invalidated()方法。

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.SimpleIntegerProperty;

public class Main {
  public static void main(String[] args) {
    SimpleIntegerProperty xProperty = new SimpleIntegerProperty(0);

    // Adding a invalidation listener (anonymous inner class)
    xProperty.addListener(new InvalidationListener() {
      @Override
      public void invalidated(Observable o) {
        System.out.println(o.toString());
      }
    });

    // Adding a invalidation listener (lambda expression)
    xProperty.addListener((Observable o) -> {
      System.out.println(o.toString());
    });

  }
}

ChangeListenerinvalidationListener之間的區別。

  • 使用ChangeListener將可獲取Observable(ObservableValue)的舊值和新值。
  • 使用invalidationListener只獲取Observable物件(屬性)