JavaFX:使用来自不同类的模型填充 TableView [英] JavaFX: Populating TableView with models from different classes
问题描述
我知道有 20 个主题与此相关,但没有一个真正对我有用.
我有 2 个模型,我想从中填充 tableView.
一个是有姓、名和东西的学生.
第二个叫做 Termin(日期可能是英文).它有一个名为 Awlist 的二维列表,我们在其中存储学生在特定日期迟到的时间.我们这样做是因为我们使用的是 ORMlite,它与其他东西并没有真正的不同.
我想要 4 列学生和 1 列,让我知道学生那天太晚了.但我真的无法和我的团队一起解决.
现在的情况:
idColumn.setCellValueFactory(new PropertyValueFactory("id"));vornameColumn.setCellValueFactory(new PropertyValueFactory("vn"));nachnameColumn.setCellValueFactory(new PropertyValueFactory("nn"));matrikelnummerColumn.setCellValueFactory(new PropertyValueFactory("matnr"));gruppeColumn.setCellValueFactory(cellData -> {if (cellData.getValue() == null)返回新的 SimpleStringProperty("");别的返回新的 SimpleStringProperty(cellData.getValue().getGroup().getBezeichnung());});fehlzeitColumn.setCellValueFactory(new PropertyValueFactory("fehlZeit"));tableView.setItems(getTableViewList());</code>
这个叫做fehlZeit"的东西是学生来晚了.
我没有显示所有调用它的 List 方法.正确实施它只是一个问题.我知道它应该是这样的,然后 getColumns().addAll 而不是 setItems() 对吗?
fehlzeitColumn.setCellValueFactory(new PropertyValueFactory("fehlZeit"));
您的问题不清楚如何从数据库中检索数据或为什么不能在查询中合并数据,因此我将演示如何使用多个用于填充 TableView
的对象模型.
TableView
只能显示一种类型的项目,因此您不能简单地将不同的对象组合成一个 TableView
.解决这个问题的方法是创建一个包装类来保存您想要的来自两个对象的数据.
下面的示例将演示一种方法来做到这一点.共有三个类:Student
、Times
和 DisplayStudent
.Student
和 Time
对象都将来自您的数据库.
然后我们构建一个 DisplayStudent
对象列表,结合 Student
和 Times
,基于匹配的 StudentId代码> 属性.
然后我们可以在 TableView
中显示我们的 DisplayStudent
对象列表.
import javafx.application.Application;导入 javafx.beans.property.*;导入 javafx.collections.FXCollections;导入 javafx.collections.ObservableList;导入 javafx.geometry.Insets;导入 javafx.geometry.Pos;导入 javafx.scene.Scene;导入 javafx.scene.control.TableColumn;导入 javafx.scene.control.TableView;导入 javafx.scene.layout.VBox;导入 javafx.stage.Stage;公共类 TableViewMultiModel 扩展应用程序 {公共静态无效主(字符串 [] args){发射(参数);}@覆盖公共无效开始(阶段primaryStage){//简单的界面VBox 根 = 新 VBox(5);root.setPadding(new Insets(10));root.setAlignment(Pos.CENTER);//*** 创建我们的样本数据(这两个列表将来自您的数据库)ObservableList学生 = FXCollections.observableArrayList();ObservableList时间 = FXCollections.observableArrayList();//这是我们的 DisplayStudents 列表,它将我们所有的数据合并到一个 TableView 模型中ObservableListdisplayStudents = FXCollections.observableArrayList();//*** 现在填充我们的列表(同样,将从您的数据库中填充学生.addAll(新学生(1,杰克"),新学生(2,布瑞恩"));时间.addAll(新时代(1,14:42"),新时代(2,4:00"),新时代(1,1:23"),新时代(1,2:20"),新时代(2, "1:03"));//*** 现在,我们需要将两个列表中的项目组合成将显示的 DisplayStudent 对象//*** 在我们的 TableView 中.通常,您会使用 SQL 查询来执行此操作,但这取决于您的数据库.对于(时间:次){//对于每个时间,我们要从学生列表中检索相应的学生.我们将使用//Java 8 Streams API 来执行此操作学生流()//检查学生列表是否包含具有此 ID 的学生.filter(p -> p.getStudentId() == time.getStudentId()).findFirst()//将新的 DisplayStudent 添加到列表中.ifPresent(s -> {displayStudents.add(new DisplayStudent(,时间));});}//*** 现在我们的模型是有序的,让我们创建我们的 TableViewTableView<DisplayStudent>tableView = 新的 TableView<>();TableColumncolName = new TableColumn<>("Name");TableColumncolTime = new TableColumn<>("Late Minutes");colName.setCellValueFactory(f -> f.getValue().getStudent().nameProperty());colTime.setCellValueFactory(f -> f.getValue().getTimes().timeProperty());tableView.getColumns().addAll(colName, colTime);tableView.setItems(displayStudents);root.getChildren().add(tableView);//显示舞台primaryStage.setWidth(300);primaryStage.setHeight(300);primaryStage.setScene(新场景(根));primaryStage.show();}}班级学生{private final IntegerProperty studentId = new SimpleIntegerProperty();private final StringProperty name = new SimpleStringProperty();公共学生(int id,字符串名称){this.studentId.setValue(id);this.name.set(name);}公共 int getStudentId() {返回 studentId.get();}公共 IntegerProperty studentIdProperty() {返回学生ID;}public void setStudentId(int studentId) {this.studentId.set(studentId);}公共字符串 getName() {返回名称.get();}公共 StringProperty nameProperty() {返回名称;}公共无效集名称(字符串名称){this.name.set(name);}}班次{私人 int studentId;private final StringProperty time = new SimpleStringProperty();公共时间(int studentId,字符串时间){this.studentId = studentId;this.time.set(time);}公共 int getStudentId() {返回学生ID;}public void setStudentId(int studentId) {this.studentId = studentId;}公共字符串 getTime() {返回时间.get();}公共 StringProperty timeProperty() {回程时间;}公共无效设置时间(字符串时间){this.time.set(time);}}类显示学生{私有最终 ObjectPropertystudent = new SimpleObjectProperty<>();私有最终 ObjectProperty<Times>times = new SimpleObjectProperty<>();public DisplayStudent(学生学生,时代次){this.student.set(student);this.times.set(times);}公共学生 getStudent() {返回学生.get();}public ObjectProperty学生属性(){返校生;}公共无效setStudent(学生学生){this.student.set(student);}公共时间 getTimes() {返回时间.get();}public ObjectProperty时间属性(){返程次数;}public void setTimes(Times times) {this.times.set(times);}}
<小时><块引用>
结果:
I know there are 20 threads about this, but nothing really has worked for me.
I have 2 models which I want to populate the tableView from.
One is Student with a surname, name and stuff.
The second one is called Termin (date in English probably). It has a two dimensional list that is called Awlist where we store times of a student that came to late at a specific day. We do this because we're using ORMlite and it won't really work different with something else.
I want 4 columns of student and 1 column that gives me the time the student was too late at that day. But I really can't fix it with my group.
How it is right now:
idColumn.setCellValueFactory(new PropertyValueFactory<Student, String>("id"));
vornameColumn.setCellValueFactory(new PropertyValueFactory<Student, String>("vn"));
nachnameColumn.setCellValueFactory(new PropertyValueFactory<Student, String>("nn"));
matrikelnummerColumn.setCellValueFactory(new PropertyValueFactory<Student, String>("matnr"));
gruppeColumn.setCellValueFactory(cellData -> {
if (cellData.getValue() == null)
return new SimpleStringProperty("");
else
return new SimpleStringProperty(cellData.getValue().getGroup().getBezeichnung());
});
fehlzeitColumn.setCellValueFactory(new PropertyValueFactory<Student, String>("fehlZeit"));
tableView.setItems(getTableViewList());</code>
This thing called "fehlZeit" is the time the student was too late.
I don't show all the List methods that call it. It's just a problem to implement it right. I know it should be like this then and getColumns().addAll instead of setItems() am I right?
fehlzeitColumn.setCellValueFactory(new PropertyValueFactory<Student, String>("fehlZeit"));
Your question is not clear on how you retrieve your data from the database or why you cannot combine the data in your queries, so I will demonstrate how to use multiple object models to populate your TableView
.
The TableView
can only display items of one type, so you cannot simply combine different objects into a single TableView
. The way around this is to create a wrapper class that holds the data you want from both objects.
The example below will demonstrate one way to do this. There are three class: Student
, Times
, and DisplayStudent
. Both Student
and Time
objects would come from your database.
We then build a list of DisplayStudent
objects, combining both the Student
and the Times
, based on matching StudentId
properties.
We can then display our list of DisplayStudent
objects in the TableView
.
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TableViewMultiModel extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// Simple interface
VBox root = new VBox(5);
root.setPadding(new Insets(10));
root.setAlignment(Pos.CENTER);
// *** CREATE OUR SAMPLE DATA (these two lists would come from your database)
ObservableList<Student> students = FXCollections.observableArrayList();
ObservableList<Times> times = FXCollections.observableArrayList();
// This is our list of DisplayStudents that combines all our data into one model for the TableView
ObservableList<DisplayStudent> displayStudents = FXCollections.observableArrayList();
// *** Now populate our lists (again, would be filled from your database
students.addAll(
new Student(1, "Jack"),
new Student(2, "Breane")
);
times.addAll(
new Times(1, "14:42"),
new Times(2, "4:00"),
new Times(1, "1:23"),
new Times(1, "2:20"),
new Times(2, "1:03")
);
// *** Now, we need to combine the items from the two lists into DisplayStudent objects which will be shown
// *** in our TableView. Normally, you'd be doing this with SQL queries, but that depends on your database.
for (Times time :
times) {
// For each Times, we want to retrieve the corresponding Student from the students list. We'll use the
// Java 8 Streams API to do this
students.stream()
// Check if the students list contains a Student with this ID
.filter(p -> p.getStudentId() == time.getStudentId())
.findFirst()
// Add the new DisplayStudent to the list
.ifPresent(s -> {
displayStudents.add(new DisplayStudent(
s,
time
));
});
}
// *** Now that our model is in order, let's create our TableView
TableView<DisplayStudent> tableView = new TableView<>();
TableColumn<DisplayStudent, String> colName = new TableColumn<>("Name");
TableColumn<DisplayStudent, String> colTime = new TableColumn<>("Late Minutes");
colName.setCellValueFactory(f -> f.getValue().getStudent().nameProperty());
colTime.setCellValueFactory(f -> f.getValue().getTimes().timeProperty());
tableView.getColumns().addAll(colName, colTime);
tableView.setItems(displayStudents);
root.getChildren().add(tableView);
// Show the Stage
primaryStage.setWidth(300);
primaryStage.setHeight(300);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
class Student {
private final IntegerProperty studentId = new SimpleIntegerProperty();
private final StringProperty name = new SimpleStringProperty();
public Student(int id, String name) {
this.studentId.setValue(id);
this.name.set(name);
}
public int getStudentId() {
return studentId.get();
}
public IntegerProperty studentIdProperty() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId.set(studentId);
}
public String getName() {
return name.get();
}
public StringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
}
class Times {
private int studentId;
private final StringProperty time = new SimpleStringProperty();
public Times(int studentId, String time) {
this.studentId = studentId;
this.time.set(time);
}
public int getStudentId() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public String getTime() {
return time.get();
}
public StringProperty timeProperty() {
return time;
}
public void setTime(String time) {
this.time.set(time);
}
}
class DisplayStudent {
private final ObjectProperty<Student> student = new SimpleObjectProperty<>();
private final ObjectProperty<Times> times = new SimpleObjectProperty<>();
public DisplayStudent(Student student, Times times) {
this.student.set(student);
this.times.set(times);
}
public Student getStudent() {
return student.get();
}
public ObjectProperty<Student> studentProperty() {
return student;
}
public void setStudent(Student student) {
this.student.set(student);
}
public Times getTimes() {
return times.get();
}
public ObjectProperty<Times> timesProperty() {
return times;
}
public void setTimes(Times times) {
this.times.set(times);
}
}
The Result:
这篇关于JavaFX:使用来自不同类的模型填充 TableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!