Reputation: 1794
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"));
Upvotes: 1
Views: 1986
Reputation: 10253
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:
Upvotes: 4