我有两个几乎相似的用于存储简单字符串数据的自定义类 - 它们被称为“患者”和“跟踪”。它们彼此之间的区别仅在于已定义字段的数量。两者的构造函数如下所示(使用getVariablesNames()
静态方法):
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”类的构造函数:
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>
类如下所示:
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);
}
}
使用“Patient”和“Trace”对象的自定义TableView的示例实现:
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应用程序的结果如下所示:
PS我没有收到任何错误。
答案 0 :(得分:3)
问题是您传递给PropertyValueFactory
的值与属性的名称不匹配,这些属性由get...()
和set...(...)
方法定义。
由于您使用反射来查找已定义的字段(而非属性)的名称,因此对于Trace
类,传递给PropertyValueFactory
的值为“动作”,“状态”,“消息”和“时间”。因此,表视图将尝试通过在每行getAction()
个对象上调用getStatus()
,getMessage()
,getTime()
和Trace
来填充列的值。由于没有这样的方法,因此您不会显示任何值。
要解决此问题,您可以执行以下操作之一:
getVariablesNames()
方法中定义的值进行硬编码以返回属性的名称(即return new String[] {"actionText", "statusText", "messageText", "timeText"};
)。由于您在每个类中重复该方法而不是重复使用它,因此您不会使事情变得更加冗长,并且这可能会表现得更好(尽管您不太可能在实践中发现任何差异)。actionText
等)。这当然会对您的类定义强加约定要求。