4

我正忙于完成一个教程并且被困在一个点上。

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

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

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

我应该使用 SimpleStringProperty 还是像 String 这样的普通对象? 在此处输入图像描述

人物类

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", "jp@me.co.za"),
    new Person("Chrispie", "Pieters", "chrispie@me.co.za")
);

@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>
4

1 回答 1

9

您需要将属性获取器的名称更改为nameProperty(),其中name是您的属性。所以你会有 firstNameProperty() 和 emailProperty()。

getName() 有效,但表不会观察到属性的变化。

PropertyValueFactory 的文档解释了这个主题:

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

如果不存在与此模式匹配的方法,则支持尝试调用 get() 或 is()(即上面示例中的 getFirstName() 或 isFirstName())。如果存在与此模式匹配的方法,则从此方法返回的值包装在 ReadOnlyObjectWrapper 中并返回给 TableCell。但是,在这种情况下,这意味着 TableCell 将无法观察 ObservableValue 的变化(就像上面第一种方法中的情况一样)。

于 2012-11-22T20:24:37.730 回答