2012-11-14 66 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()更改列表或设置值(作为示例) –