2012-11-14 104 views
8

,所以我想學習如何使用了JavaFx泰伯維,我碰到這個教程stumpled:SimpleStringProperty和SimpleIntegerProperty TableView中的JavaFX

Oracle tableview tutorial

在本教程中,他們顯示,以填補你的tableView你必須填充字符串,但不是任何字符串,你必須格式化你StringSimpleStringProperty

我試過沒有格式,結果是沒有任何信息會顯示!

而且我發現,如果你想要一個Integer添加到表你就必須把它宣佈爲SimpleIntegerProperty

現在我是相當新的了JavaFx但是這是否意味着,當我創建一個對象,我有格式化所有我的整數和字符串,以便能夠填充我的TableView?它似乎相當愚蠢,但也許有更高的目的?還是有辦法避免它?

+0

這是一個寫得不好的教程。他們掩蓋了太多重要的觀點,例如泛型。 –

回答

23

雖然在某些情況下需要使用屬性,但您不需要在表數據對象中使用Properties來顯示屬性。

下面的代碼將顯示基於僅具有字符串字段的Person類的人員表。

import javafx.application.Application; 
import javafx.collections.*; 
import javafx.geometry.Insets; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.VBox; 
import javafx.scene.text.Font; 
import javafx.stage.Stage; 

public class ReadOnlyTableView extends Application { 
    private TableView<Person> table = new TableView<Person>(); 
    private final ObservableList<Person> data = 
    FXCollections.observableArrayList(
     new Person("Jacob", "Smith", "[email protected]"), 
     new Person("Isabella", "Johnson", "[email protected]"), 
     new Person("Ethan", "Williams", "[email protected]"), 
     new Person("Emma", "Jones", "[email protected]"), 
     new Person("Michael", "Brown", "[email protected]") 
    ); 

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

    @Override public void start(Stage stage) { 
    stage.setTitle("Table View Sample"); 
    stage.setWidth(450); 
    stage.setHeight(500); 

    final Label label = new Label("Address Book"); 
    label.setFont(new Font("Arial", 20)); 

    TableColumn firstNameCol = new TableColumn("First Name"); 
    firstNameCol.setMinWidth(100); 
    firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 

    TableColumn lastNameCol = new TableColumn("Last Name"); 
    lastNameCol.setMinWidth(100); 
    lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 

    TableColumn emailCol = new TableColumn("Email"); 
    emailCol.setMinWidth(200); 
    emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 

    table.setItems(data); 
    table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 

    final VBox vbox = new VBox(); 
    vbox.setSpacing(5); 
    vbox.setPadding(new Insets(10, 0, 0, 10)); 
    vbox.getChildren().addAll(label, table); 

    stage.setScene(new Scene(new Group(vbox))); 
    stage.show(); 
    } 

    public static class Person { 
    private String firstName; 
    private String lastName; 
    private String email; 

    private Person(String fName, String lName, String email) { 
     this.firstName = fName; 
     this.lastName = lName; 
     this.email = email; 
    } 

    public String getFirstName() { return firstName; } 
    public void setFirstName(String fName) { firstName = fName; } 
    public String getLastName() { return lastName; } 
    public void setLastName(String lName) { lastName = lName; } 
    public String getEmail() { return email; } 
    public void setEmail(String inMail) { email = inMail; } 
    } 
} 

說明

使用性能及ObservableLists的目的是,這些是可聽元素。使用屬性時,如果數據模型中屬性屬性的值發生更改,則TableView中的項目視圖會自動更新以匹配更新的數據模型值。例如,如果某個人的電子郵件屬性的值設置爲新值,則該更新將反映在TableView中,因爲它會偵聽屬性更改。相反,如果使用純String代表電子郵件,則TableView將不會刷新,因爲它不會意識到電子郵件值更改。

PropertyValueFactory文檔詳細描述了這一過程:

的如何使用這個類的一個例子是:

TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name"); 
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person,String>("firstName")); 

在這個例子中,「名字」的字符串被用作參考以 假設Person類類型(即 TableView項列表的類類型)中的firstNameProperty()方法。此外,此方法 必須返回一個Property實例。如果找到符合這些 要求的方法,則TableCell將填充此ObservableValue。此外,TableView會自動將 觀察者添加到返回值中,以便TableView觀察到的任何更改觸發爲 ,從而導致單元立即更新。

如果沒有方法匹配該模式的存在,對於試圖呼叫得到()是()(即 是,的getFirstName()或isFirstName()在上面的例子)落空 支持或。如果存在匹配此模式的方法 ,則從此方法返回的值爲 ,該值包裝在ReadOnlyObjectWrapper中並返回到TableCell。然而,在這種情況下,這意味着TableCell不會是 能夠觀察ObservableValue的變化(如上面的第一種方法 )。

更新

這裏是一個對比鮮明的例子,它說明了一個TableView中如何觀察和自動刷新基礎上更改它的項目和變化的ObservableList到基於屬性項的值的第一個例子屬性。

import javafx.application.Application; 
import javafx.beans.property.*; 
import javafx.collections.*; 
import javafx.event.*; 
import javafx.geometry.Insets; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.VBox; 
import javafx.scene.text.Font; 
import javafx.stage.Stage; 

public class PropertyBasedTableView extends Application { 
    private TableView<Person> table = new TableView<Person>(); 
    private final ObservableList<Person> data = FXCollections.observableArrayList(); 
    private void initData() { 
    data.setAll(
     new Person("Jacob", "Smith", "[email protected]"), 
     new Person("Isabella", "Johnson", "[email protected]"), 
     new Person("Ethan", "Williams", "[email protected]"), 
     new Person("Emma", "Jones", "[email protected]"), 
     new Person("Michael", "Brown", "[email protected]") 
    ); 
    } 

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

    @Override public void start(Stage stage) { 
    initData(); 

    stage.setTitle("Table View Sample"); 
    stage.setWidth(450); 
    stage.setHeight(500); 

    final Label label = new Label("Address Book"); 
    label.setFont(new Font("Arial", 20)); 

    TableColumn firstNameCol = new TableColumn("First Name"); 
    firstNameCol.setMinWidth(100); 
    firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 

    TableColumn lastNameCol = new TableColumn("Last Name"); 
    lastNameCol.setMinWidth(100); 
    lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 

    TableColumn emailCol = new TableColumn("Email"); 
    emailCol.setMinWidth(200); 
    emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 

    table.setItems(data); 
    table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 
    table.setPrefHeight(300); 

    final Button setEmailButton = new Button("Set first email in table to [email protected]"); 
    setEmailButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override public void handle(ActionEvent event) { 
     if (data.size() > 0) { 
      data.get(0).setEmail("[email protected]"); 
     } 
     } 
    }); 

    final Button removeRowButton = new Button("Remove first row from the table"); 
    removeRowButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override public void handle(ActionEvent event) { 
     if (data.size() > 0) { 
      data.remove(0); 
     } 
     } 
    }); 

    final Button resetButton = new Button("Reset table data"); 
    resetButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override public void handle(ActionEvent event) { 
     initData(); 
     } 
    }); 

    final VBox vbox = new VBox(10); 
    vbox.setPadding(new Insets(10, 0, 0, 10)); 
    vbox.getChildren().addAll(label, table, setEmailButton, removeRowButton, resetButton); 

    stage.setScene(new Scene(new Group(vbox))); 
    stage.show(); 
    } 

    public static class Person { 
    private final StringProperty firstName; 
    private final StringProperty lastName; 
    private final StringProperty email; 

    private Person(String fName, String lName, String email) { 
     this.firstName = new SimpleStringProperty(fName); 
     this.lastName = new SimpleStringProperty(lName); 
     this.email = new SimpleStringProperty(email); 
    } 

    public String getFirstName() { return firstName.get(); } 
    public void setFirstName(String fName) { firstName.set(fName); } 
    public StringProperty firstNameProperty() { return firstName; } 
    public String getLastName() { return lastName.get(); } 
    public void setLastName(String lName) { lastName.set(lName); } 
    public StringProperty lastNameProperty() { return lastName; } 
    public String getEmail() { return email.get(); } 
    public void setEmail(String inMail) { email.set(inMail); } 
    public StringProperty emailProperty() { return email; } // if this method is commented out then the tableview will not refresh when the email is set. 
    } 
} 
+0

首先非常感謝你的回覆,如果我可以給你超過1個大拇指:) 第二,所以你說什麼是通過將字符串轉換爲SimpleStringProperty表會自動更新?而選擇不去,你將不得不更新表manuelly? –

+0

從PropertyValueFactory添加了一個引用來解答Marc的附加問題的答案。 – jewelsea

+0

當某個屬性發生更改時,該表是否會自動更新?如果是,您將如何執行此操作?你是否使用object.setName()更改列表或設置值(作爲示例) –