的TableView< T>不显示ObservableList< T>的内容对象 [英] TableView<T> does not display the content of ObservableList<T> objects

查看:87
本文介绍了的TableView< T>不显示ObservableList< T>的内容对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个几乎相似的用于存储简单字符串数据的自定义类 - 它们被称为患者和跟踪。它们彼此之间的区别仅在于已定义字段的数量。两者的构造函数如下所示(使用 getVariablesNames()静态方法):

I have two almost similar custom classes for storing simple String data - they are called "Patient" and "Trace".They differ from eachother only by the number of defined fields. Constructors of both are shown below (with getVariablesNames() static method):

public class Patient {

    String patientID;
    String firstName;
    String lastName;
    String gender;
    String dateOfBirth;
    String age;
    String email;
    String phoneNumber;
    String city;

    public Patient(String patientID, String firstName, String lastName, String gender, String dateOfBirth, String age, String email, String phoneNumber, String city) {
        this.patientID = patientID;
        this.firstName = firstName;
        this.lastName = lastName;
        this.gender = gender;
        this.dateOfBirth = dateOfBirth;
        this.age = age;
        this.email = email;
        this.phoneNumber = phoneNumber;
        this.city = city;
    }

    public static String[] getVariablesNames() {
        Field[] fields = Patient.class.getDeclaredFields();
        String[] variablesNames = new String[fields.length];
        for (int i = 0; i < fields.length; i++) {
            variablesNames[i] = fields[i].getName();
        }
        return variablesNames;
    }

    public String getPatientID() {
        return patientID;
    }

    public void setPatientID(String value) {
        patientID = value;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String value) {
        firstName = value;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String value) {
        lastName = value;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String value) {
        gender = value;
    }

    public String getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(String value) {
        dateOfBirth = value;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String value) {
        age = value;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String value) {
        email = value;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String value) {
        phoneNumber = value;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String value) {
        city = value;
    }
}

Trace类的构造函数:

And constructor for "Trace" class:

public class Trace {

    String action;
    String status;
    String message;
    String time;

    public Trace(String action, String status, String message, String time) {
        this.action = action;
        this.status = status;
        this.message = message;
        this.time = time;
    }

    public static String[] getVariablesNames() {
        Field[] fields = Trace.class.getDeclaredFields();
        String[] variablesNames = new String[fields.length];
        for (int i = 0; i < fields.length; i++) {
            variablesNames[i] = fields[i].getName();
        }
        return variablesNames;
    }

    public void setActionText(String value) {
        action = value;
    }

    public String getActionText() {
        return action;
    }

    public void setStatusText(String value) {
        status = value;
    }

    public String getStatusText() {
        return status;
    }

    public void setMessageText(String value) {
        message = value;
    }

    public String getMessageText() {
        return message;
    }

    public void setTimeText(String value) {
        time = value;
    }

    public String getTimeText() {
        return time;
    }
}

我使用这些类的对象来填充自定义 TableView< T> 实例,其中< T> 可以是患者或跟踪。我遇到的问题是Trace对象值没有显示在表中,其中Patient类的对象没有问题。自定义 TableView< T> 类如下所示:

I use objects of those classes to populate custom TableView<T> instances, where <T> can be "Patient" or "Trace". The problem I encounter is that "Trace" object values are not displayed in the table, where there are no problems with objects of the "Patient" class. The custom TableView<T> class is shown below:

import javafx.collections.ObservableList;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;

public class TableViewCustom<T> extends TableView<T> {

    public TableViewCustom(String[] columnNames, String[] variablesNames, ObservableList<T> data) {
        super();

        @SuppressWarnings("unchecked")
        TableColumn<T, String>[] tableColumns = new TableColumn[variablesNames.length];
        for (int i = 0; i < tableColumns.length; i++) {
            tableColumns[i] = new TableColumn<T, String>(columnNames[i]);
            tableColumns[i].setCellValueFactory(new PropertyValueFactory<T, String>(variablesNames[i]));
        }

        this.setItems(data);
        this.getColumns().addAll(tableColumns);

        this.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    }
}

此自定义TableView的示例实现使用患者和跟踪对象:

And the example implementation of this custom TableView with use of both "Patient" and "Trace" objects:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Demo extends Application {

    public Parent createContent() {

        /* layout */
        BorderPane layout = new BorderPane();

        /* layout -> center */
        VBox tableViewsContainer = new VBox(5);

        /* layout -> center -> top */
        String[] patientColumnNames = new String[] {"Patient ID", "First Name", "Last Name", "Gender", "Date Of Birth", "Age", "Email", "Phone Number", "City"};
        String[] patientVariablesNames = Patient.getVariablesNames();
        ObservableList<Patient> patientData = FXCollections.observableArrayList(new Patient("Patient ID", "First Name", "Last Name", "Gender", "Date Of Birth", "Age", "Email", "Phone Number", "City"));
        TableViewCustom<Patient> patientTableView = new TableViewCustom<Patient>(patientColumnNames, patientVariablesNames, patientData);

        /* layout -> center -> bottom */
        String[] traceColumnNames = new String[] {"Action", "Status", "Message", "Time"};
        String[] traceVariablesNames = Trace.getVariablesNames();
        ObservableList<Trace> traceData = FXCollections.observableArrayList(new Trace("Action", "Status", "Message", "Time"));
        TableViewCustom<Trace> traceTableView = new TableViewCustom<Trace>(traceColumnNames, traceVariablesNames, traceData);

        /* add items to the layout */
        tableViewsContainer.getChildren().addAll(patientTableView, traceTableView);

        layout.setCenter(tableViewsContainer);
        return layout;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent()));
        stage.setWidth(700);
        stage.setHeight(400);
        stage.show();
    }

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

Demo.java应用程序的结果如下所示:

The result of Demo.java app is shown below:

PS我没有收到任何错误。

PS I'm not getting any errors.

推荐答案

问题在于价值观您传递给 PropertyValueFactory 与属性名称不匹配,属性由 get ...()设置...(...)方法。

The problem is that the values you are passing to the PropertyValueFactory do not match the names of the properties, which are defined by the get...() and set...(...) methods.

因为你正在使用反射来查找您已定义的字段(不是属性)的名称,跟踪类传递给 PropertyValueFactory <的值/ code>是动作,状态,消息和时间。因此,表视图将尝试通过调用 getAction() getStatus(),<填充列的值。 code> getMessage(),以及跟踪对象上的 getTime()在每一行。由于没有这样的方法,您不会显示任何值。

Since you are using reflection to look up the names of the fields (not the properties) you have defined, for the Trace class the values passed to PropertyValueFactory are "action", "status", "message", and "time". So the table view will attempt to populate the values for the columns by calling getAction(), getStatus(), getMessage(), and getTime() on the Trace objects in each row. Since there are no such methods, you don't get any values displayed.

要解决此问题,您可以执行以下操作之一:

To fix this, you can do one of the following:


  1. 硬编码在 getVariablesNames()方法中定义的值,以返回属性的名称(即 return new String [] {actionText,statusText,messageText,timeText}; )。由于您在每个类中重复该方法而不是重复使用它,因此您不会使事情变得更加冗长,并且这可能会表现得更好(尽管您不太可能在实践中发现任何差异)。

  2. 使用反射,但查找声明的方法的名称,查找所有以get或is开头的内容,剥去该前缀,并小写剩下的第一个字符。

  3. 使字段名称与属性名称匹配(即将字段声明为 actionText 等)。这当然会对您的类定义强加约定要求。

  1. Hard code the values defined in your getVariablesNames() method to return the names of the properties (i.e. return new String[] {"actionText", "statusText", "messageText", "timeText"};). Since you repeat the method in each class rather than reusing it, you don't make things more verbose, and this would potentially perform better (though you are unlikely to observe any differences in practice).
  2. Use reflection, but look up the names of the declared methods, find all those beginning "get" or "is", strip off that prefix, and lower-case the first character of what remains.
  3. Make the field names match the property names (i.e. declare the fields as actionText, etc.). This of course imposes convention requirements on your class definition.

这篇关于的TableView&LT; T&GT;不显示ObservableList&lt; T&gt;的内容对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆