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: