2012-11-22 100 views
4

我正在忙于编写教程,并被困在一点上。JavaFx - 如何在TableView中显示SimpleStringProperty值

基本上在表视图中启动新场景并从ObservableList类型Person中显示值。

person类由3个SimpleStringProperty的firsName,lastName和email组成。

但是,当我运行应用程序似乎显示表中的SimpleStringProperty [StringProperty [value:actualvalue]]的值,而不是SimpleStringProperty的值。如果我将Person的类getFirstName方法更改为返回String firstName.get(),则它会在表中正确显示值。

我应该使用SimpleStringProperty还是像String这样的普通对象? enter image description here

Person类

package co.za.chrispie.addressBook; 

import javafx.beans.property.SimpleStringProperty; 

public class Person { 

private SimpleStringProperty firstName; 
private SimpleStringProperty lastName; 
private SimpleStringProperty email; 

public Person(final String firstName, final String lastName, final String email) { 
    this.firstName = new SimpleStringProperty(firstName); 
    this.lastName = new SimpleStringProperty(lastName); 
    this.email = new SimpleStringProperty(email); 
} 

public String getFirstName() { 
    return firstName.get(); //Changes this method to return a String 
} 

public SimpleStringProperty getLastName() { 
    return lastName; 
} 

public SimpleStringProperty getEmail() { 
    return email; 
} 

} 

控制器类

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package co.za.chrispie.addressBook; 

import java.net.URL; 
import java.util.ResourceBundle; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.PropertyValueFactory; 

public class OracleAddressBookController implements Initializable { 

@FXML 
TableView<Person> table; 
@FXML 
TableColumn<Person, String> colFirstName; 
@FXML 
TableColumn<Person, String> colLastName; 
@FXML 
TableColumn<Person, String> colEmail; 

final ObservableList<Person> data = FXCollections.observableArrayList(
    new Person("Jaco", "Pieters", "[email protected]"), 
    new Person("Chrispie", "Pieters", "[email protected]") 
); 

@Override 
public void initialize(URL url, ResourceBundle rb) { 
    assert colFirstName != null : "fx:id=\"colFirstName\" was not injected: check your FXML file 'OracleAddressBook.fxml'."; 
    assert colLastName != null : "fx:id=\"colLastName\" was not injected: check your FXML file 'OracleAddressBook.fxml'."; 
    assert colEmail != null : "fx:id=\"colEmail\" was not injected: check your FXML file 'OracleAddressBook.fxml'."; 
    configureTable(); 
}  

private void configureTable() { 
    colFirstName.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 
    colLastName.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 
    colEmail.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 

    table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); 

    table.setItems(data); 
    assert table.getItems() == data; 
} 
} 

和前端FXML

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import java.net.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<AnchorPane id="AnchorPane" prefHeight="500.0" prefWidth="600.0" styleClass="mainFxmlClass" xmlns:fx="http://javafx.com/fxml" fx:controller="co.za.chrispie.addressBook.OracleAddressBookController"> 
<children> 
    <Label layoutX="14.0" layoutY="11.0" text="Address Book" /> 
    <TableView fx:id="table" layoutX="14.0" layoutY="35.0" prefHeight="451.0" prefWidth="572.0"> 
    <columns> 
    <TableColumn prefWidth="75.0" text="First Name" fx:id="colFirstName" /> 
    <TableColumn prefWidth="75.0" text="Last Name" fx:id="colLastName" /> 
    <TableColumn prefWidth="75.0" text="Email" fx:id="colEmail" /> 
    </columns> 
</TableView> 
</children> 
    <stylesheets> 
    <URL value="@oracleaddressbook.css" /> 
</stylesheets> 
</AnchorPane> 
+1

我发现这个解释很有用:[JavaFX Property Architecture](https://wiki.openjdk.java.net/display/OpenJFX/JavaFX+Property+Architecture) – will

回答

8

你需要改变你的财产的getter的名字nameProperty(),其中名称是你的财产。所以你会有firstNameProperty()和emailProperty()。

getName()工程,但该表不会观察属性的更改。

为PropertyValueFactory的文档解释这个问题:

在这个例子中,“名字”的字符串被用作在Person类类型的引用,以假定的firstNameProperty()方法(它是类的类型TableView项目列表)。另外,这个方法必须返回一个Property实例。如果找到满足这些要求的方法,则使用此ObservableValue填充TableCell。另外,TableView会自动将观察者添加到返回的值中,以便TableView可以观察到触发的任何更改,从而导致单元立即更新。

如果没有方法匹配该模式的存在,有落空支持试图呼叫得到()或为()(即,在上面的例子中的getFirstName()或isFirstName())。如果存在与此模式匹配的方法,则从此方法返回的值将包装在ReadOnlyObjectWrapper中并返回到TableCell。但是,在这种情况下,这意味着TableCell将无法观察ObservableValue的变化(如上面第一种方法中的情况)。

相关问题