JavaFX使用OneToMany关系填充表格视图 [英] JavaFX populate tableview with a OneToMany relationship
问题描述
用一个类中的数据填充表很容易,但是当我想用OneToMany关系中的数据填充表时又是什么呢?
例如:
班级人员: ID,名字,姓氏, 汽车(汽车与"Class Cars"之间有着千丝万缕的联系,因此一个人可以拥有一辆或多辆汽车)
现在,如果一个人有两辆车,如何将它添加到桌子上?
它应该看起来像这样:
ID | firstname | lastname | vehicleBrand(from cars)
==============================================
1 | jack | jackson | crysler
----------------------------------------------
| | | bmw
----------------------------------------------
2 | sally | jackson | ford
如果我有来自人"的可观察列表,则可以这样填充人数据:
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person,String>("firstName")
);
但类似:
vehicleBrandCol.setCellValueFactory(
new PropertyValueFactory<Cars,String>("vehicleBrand")
);
或
vehicleBrandCol.setCellValueFactory(
new PropertyValueFactory<Person,String>("vehicleBrand")
);
不起作用.
以下答案适用于一个品牌.如果我尝试添加所有内容,则可以使用如下所示的循环进行尝试:
for (Car aCars : cars) {
return new SimpleObjectProperty<>(aCars.vehicleBrand());
}
但是循环不循环吗?! (我打印的是汽车尺寸,不是1)
这应该是您所寻找的一部分,您可以执行以下操作:
- 现在我假设您有两个类
Person
和Car
. -
Person
类有一个ArrayList<Car>
汽车. -
Person
类还具有方法getCars()
,该方法返回此人的汽车收藏(ArrayList
).
现在要从显示在TableView
人中的Car
类中获取品牌,您可以按以下方式设置CellValueFactory
:
vehicleBrandCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person,String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(CellDataFeatures<Person, String> param) {
ArrayList<Car> cars = new ArrayList<Car>();
cars = param.getValue().getCars();
if(cars!=null && !cars.isEmpty()) {
return new SimpleStringProperty(cars.get(0).getBrand());
}
}
}
);
param.getValue()
方法返回作为参数传递的person
.
请注意,在此示例中,我仅返回(显示)当前人员的汽车集合中的第一个汽车品牌,您可以尝试使此示例适应您的情况.
好吧,这很有意义^^我应该列出 SimpleObjectProperty并返回它?
不,您不能这样做,因为您声明的列应包含String
对象而不是List
对象.
您可以做的是创建自定义单元格,该单元格将允许您显示每个Person
实例的所有Car
品牌,您可以查看
,然后您将需要自定义单元格来显示此ArrayList
中包含的数据(汽车),因此请按以下方式设置CellFactory
:
vehicleBrandCol.setCellFactory(column->{
return new TableCell<Person, ArrayList<Car>>() {
@Override
protected void updateItem(ArrayList<Car> item, boolean empty) {
super.updateItem(item, empty);
if(item==null || empty) {
setGraphic(null);
} else {
VBox vbox = new VBox();
for(Car car : item) {
Label lbl = new Label(car.getBrand());
vbox.getChildren().add(lbl);
}
setGraphic(vbox);
}
}
};
});
请注意,我正在创建VBox
并使用标签,您可以使用任何喜欢的Node
,例如,可以使用ListView
或GridPane
并将它们设置为Cell
.
to populate a table is easy when you populate it with data from one class, but what is when I want to populate it with data from a OneToMany relationship?
for example:
Class Person: Id, firstname, lastname, cars(cars have a onetomany relationship with Class Cars, so one person can have one or more cars)
Now, if a person got two cars, how can I add this to a table?
It should look something like this:
ID | firstname | lastname | vehicleBrand(from cars)
==============================================
1 | jack | jackson | crysler
----------------------------------------------
| | | bmw
----------------------------------------------
2 | sally | jackson | ford
If I have the observable list from Person I can populate the person data like this:
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person,String>("firstName")
);
but something like:
vehicleBrandCol.setCellValueFactory(
new PropertyValueFactory<Cars,String>("vehicleBrand")
);
or
vehicleBrandCol.setCellValueFactory(
new PropertyValueFactory<Person,String>("vehicleBrand")
);
does not work.
Edit: The answer below works for one brand. If I try to add all I tried it by using a loop like this:
for (Car aCars : cars) {
return new SimpleObjectProperty<>(aCars.vehicleBrand());
}
But the loop does not loop?! (I printed the size of cars and it is not 1)
This should be part of what you are looking for, you can do this:
- Now I'm supposing you have the two classes
Person
andCar
. - The class
Person
has anArrayList<Car>
of cars. - The class
Person
has also a methodgetCars()
which returns this person's collection (theArrayList
) of cars.
Now to get the brand from your Car
class displayed in the TableView
of persons you can set the CellValueFactory
as follows:
vehicleBrandCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person,String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(CellDataFeatures<Person, String> param) {
ArrayList<Car> cars = new ArrayList<Car>();
cars = param.getValue().getCars();
if(cars!=null && !cars.isEmpty()) {
return new SimpleStringProperty(cars.get(0).getBrand());
}
}
}
);
The param.getValue()
method returns the person
passed as a parameter.
Notice that in this example I'm returning(displaying) only the first car brand from the collection of cars of the current person, you can try to adapt this example to your case.
Ok, that makes sense ^^ should I make a List of the SimpleObjectProperty and return this?
No you can't do this because you are declaring a column that should contain String
objects not List
objects.
What you can do is create custom cells that would allow you display all of the Car
brands of a each Person
instance, you can take a look at this example to get a grasp of Cell rendering, and here is my example that could help you in your case:
First set the type of the content of cells in vehicleBrandCol
to ArrayList<String>
:
private TableColumn<Person, ArrayList<Car>> vehicleBrandCol;
Then set the CellValueFactory
as follows:
vehicleBrandCol.setCellValueFactory(new PropertyValueFactory<Person, ArrayList<Car>>("cars"));
and then you'll need custom cells to display data (Cars) contained within this ArrayList
, so set the CellFactory
as follows:
vehicleBrandCol.setCellFactory(column->{
return new TableCell<Person, ArrayList<Car>>() {
@Override
protected void updateItem(ArrayList<Car> item, boolean empty) {
super.updateItem(item, empty);
if(item==null || empty) {
setGraphic(null);
} else {
VBox vbox = new VBox();
for(Car car : item) {
Label lbl = new Label(car.getBrand());
vbox.getChildren().add(lbl);
}
setGraphic(vbox);
}
}
};
});
Notice that I'm creating a VBox
and using Labels, you can use whatever Node
you like, for example you can use a ListView
, or a GridPane
and set them as graphic for the Cell
.
这篇关于JavaFX使用OneToMany关系填充表格视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!