如何使用Javafx的TreeTableView控件构建展示类的树状列表界面?

2026-04-18 00:371阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1752个文字,预计阅读时间需要8分钟。

如何使用Javafx的TreeTableView控件构建展示类的树状列表界面?

使用Javafx插件中的TreeTableView控件,以树状表格的形式展示类。在开发Javafx插件项目时,需要将房屋信息以树状表格的形式呈现。实现效果:1、简单介绍;在这里简单介绍。

使用Javafx插件的TreeTableView控件,令一个类以树状表格的形式显示。

在使用Javafx插件开发作业项目时,我需要将房屋以树状表格的形式显示出来。
实现的效果:

1、简单介绍

在这里简单介绍一下我的程序中涉及到的类的属性。

在我的程序中,需要显示的类为House类。

House类的属性如下所示。我需要将楼盘、房屋编号、购房合同编号、移交日期、所属会员ID与备注显示在表格中。

public class House implements Serializable { String code = "";//房屋编号 String houseName = "";//楼盘 String houseNumber = "";//楼号 String houseFloor = "";//楼层 String roomNumber = "";//房间号 String purchaseNumber = "";//购房合同编号 String purchaseDate = "";//移交日期 String add = "";//备注 String houseOwnerID = "";//所属会员ID ...下面的代码略

使用HouseList作为House的集合类。

public class HouseList implements Iterable<House>, Serializable { public ArrayList<House> houselist = new ArrayList<>(); /** * 添加一个房屋到列表 * @param house 添加的房屋 */ public void add(House house) { this.houselist.add(house); } @Override public Iterator iterator() { return this.houselist.iterator(); } }

在Structure类中实例化一个HouseList对象。这个HouseList对象存储有要显示的房屋。

2、整体思路

我的整体的思路是:

在创建页面时,Javafx会调用页面的控制器(Controller)中的initialize()函数进行页面的初始化。

因此,我在该函数中遍历房屋列并完成树表的创建。

3、具体实现

首先使用Scene Builder创建一个页面,添加TreeTableView组件,并添加多个TreeTableColumn。

在右侧窗口设置TreeTableView与每个TreeTableColumn的fx:id。

在项目中创建一个控制类(我将其命名为AdminInterface_House_Controller),并将刚才创建的页面的fxml文件中的Controller设置为这个类。

在创建的控制类中添加属性。

注意:属性的命名与刚才设置的fx:id一致。

如何使用Javafx的TreeTableView控件构建展示类的树状列表界面?

public class AdminInterface_House_Controller { @FXML private TreeTableView<House> table; @FXML private TreeTableColumn<House, String> houseTree_List; @FXML private TreeTableColumn<House, String> purchaseNumber_List; @FXML private TreeTableColumn<House, String> purchaseDate_List; @FXML private TreeTableColumn<House, String> add_List; @FXML private TreeTableColumn<House, String> houseOwnerID_List; @FXML private TreeTableColumn<House, String> code_List; ...下面的代码省略

在这个类中创建初始化方法。我们将在这个函数中完成完成树表的创建。

@FXML private void initialize() { }

initialize()函数中,进行房屋遍历,每次循环取出一间房屋。每次循环的流程图如下所示:

为了减少initialize()中的代码,我先定义了一个repeatText()方法。这个方法输入一个ObservableList<TreeItem>与String,前者是一个占位房屋列表,后者是一个字符串。

这个函数判断是否存在一个占位房屋的roomNumber变量与输入的字符串相同。
如果存在,则说明输入的字符串重复,该函数输出重复位置。如果不存在,函数输出-1。

private int repeatText(ObservableList<TreeItem<House>> list, String text){ //输出-1代表不重复,输出其他自然数代表重复位置,如0代表与第一个节点重复 int i = -1; House temp; for (TreeItem<House> treeItem : list){ i++; temp = treeItem.getValue(); if (text.equals(temp.getRoomNumber())){ //由于输入的是占位房屋列表,只有roomNumber变量有值。所以只需要判断text是否与roomNumber相同即可。 //重复 return i; } } //不重复 return -1; }

为了便于创建占位房屋,我还在House类中重载了构造函数。

public House(String roomNumber){ this.roomNumber = roomNumber; }

initialize()函数的具体代码较为复杂,具体如下所示。

@FXML private void initialize() { //根节点root TreeItem<House> root = new TreeItem<>( new House("房屋列表")); //绑定root table.setRoot(root); root.setExpanded(true); //遍历房屋列表 for (House house : Structure.getStructure().houseList){ //对于取出的house //取楼盘 //检查重复性 if (repeatText(root.getChildren(), house.getHouseName()) == -1){ //楼盘不重复 //楼盘 //创建占位房屋,作为根节点的子节点 root.getChildren().add(new TreeItem<House>(new House(house.getHouseName()))); //楼号 int pos = root.getChildren().size()-1; //创建占位房屋,作为子节点 root.getChildren().get(pos).setExpanded(true); root.getChildren().get(pos).getChildren().add( new TreeItem<House>(new House(house.getHouseNumber())) ); //楼层 //创建占位房屋,作为子节点 root.getChildren().get(pos).getChildren().get(0).setExpanded(true); root.getChildren().get(pos).getChildren().get(0).getChildren().add( new TreeItem<House>(new House(house.getHouseFloor())) ); //房屋存入 root.getChildren().get(pos).getChildren().get(0).getChildren() .get(0).setExpanded(true); root.getChildren().get(pos).getChildren().get(0).getChildren() .get(0).getChildren().add(new TreeItem<House>(house)); }else { //楼盘重复 //楼盘在root中的位置nameRepeatPos int nameRepeatPos = repeatText(root.getChildren(), house.getHouseName()); //检查楼号重复性 if (repeatText(root.getChildren().get(nameRepeatPos).getChildren(), house.getHouseNumber()) == -1){ //楼盘重复,但楼号不重复 //楼号 root.getChildren().get(nameRepeatPos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().add( new TreeItem<House>(new House(house.getHouseNumber())) ); //楼层 int pos = root.getChildren().get(nameRepeatPos).getChildren().size()-1; root.getChildren().get(nameRepeatPos).getChildren().get(pos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(pos).getChildren().add( new TreeItem<House>(new House(house.getHouseFloor())) ); //房屋存入 root.getChildren().get(nameRepeatPos).getChildren().get(pos).getChildren() .get(0).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(pos).getChildren() .get(0).getChildren().add(new TreeItem<House>(house)); }else { //楼盘重复,楼号重复 //楼号在root中的位置numRepeatPos int numRepeatPos = repeatText(root.getChildren().get(nameRepeatPos).getChildren(), house.getHouseNumber()); //检查楼层重复性 if (repeatText( root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() , house.getHouseFloor()) == -1){ //楼盘重复,楼号重复,楼层不重复 root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren().add( new TreeItem<House>(new House(house.getHouseFloor())) ); //房屋存入 int pos = root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren().size()-1; root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() .get(pos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() .get(pos).getChildren().add(new TreeItem<House>(house)); }else { //楼盘重复,楼号重复,楼层重复 //楼层root中的位置floorRepeatPos int floorRepeatPos = repeatText( root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() , house.getHouseFloor()); //房屋存入 root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() .get(floorRepeatPos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() .get(floorRepeatPos).getChildren().add(new TreeItem<House>(house)); } } } } //向列表中添加条目 houseTree_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new eadOnlyStringWrapper(houseTemp.getValue().getValue().getRoomNumber())); purchaseNumber_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getPurchaseNumber())); code_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getCode())); houseOwnerID_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getHouseOwnerID())); add_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getAdd())); purchaseDate_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getPurchaseDate())); }

最后运行就可以达到树表的效果。

4、未来优化

由于时间比较紧张,这个部分还有很大的优化空间。由于树表计算部分设置在控制器的初始化函数中,因此每次打开房屋页面都要重新计算树表,在房屋数量较多时,这会造成性能浪费。因此,可以在创建每个新房屋时,将该房屋加入树表中,并将这个树表储存起来。每次打开页面时便免去了复杂的计算。

本文共计1752个文字,预计阅读时间需要8分钟。

如何使用Javafx的TreeTableView控件构建展示类的树状列表界面?

使用Javafx插件中的TreeTableView控件,以树状表格的形式展示类。在开发Javafx插件项目时,需要将房屋信息以树状表格的形式呈现。实现效果:1、简单介绍;在这里简单介绍。

使用Javafx插件的TreeTableView控件,令一个类以树状表格的形式显示。

在使用Javafx插件开发作业项目时,我需要将房屋以树状表格的形式显示出来。
实现的效果:

1、简单介绍

在这里简单介绍一下我的程序中涉及到的类的属性。

在我的程序中,需要显示的类为House类。

House类的属性如下所示。我需要将楼盘、房屋编号、购房合同编号、移交日期、所属会员ID与备注显示在表格中。

public class House implements Serializable { String code = "";//房屋编号 String houseName = "";//楼盘 String houseNumber = "";//楼号 String houseFloor = "";//楼层 String roomNumber = "";//房间号 String purchaseNumber = "";//购房合同编号 String purchaseDate = "";//移交日期 String add = "";//备注 String houseOwnerID = "";//所属会员ID ...下面的代码略

使用HouseList作为House的集合类。

public class HouseList implements Iterable<House>, Serializable { public ArrayList<House> houselist = new ArrayList<>(); /** * 添加一个房屋到列表 * @param house 添加的房屋 */ public void add(House house) { this.houselist.add(house); } @Override public Iterator iterator() { return this.houselist.iterator(); } }

在Structure类中实例化一个HouseList对象。这个HouseList对象存储有要显示的房屋。

2、整体思路

我的整体的思路是:

在创建页面时,Javafx会调用页面的控制器(Controller)中的initialize()函数进行页面的初始化。

因此,我在该函数中遍历房屋列并完成树表的创建。

3、具体实现

首先使用Scene Builder创建一个页面,添加TreeTableView组件,并添加多个TreeTableColumn。

在右侧窗口设置TreeTableView与每个TreeTableColumn的fx:id。

在项目中创建一个控制类(我将其命名为AdminInterface_House_Controller),并将刚才创建的页面的fxml文件中的Controller设置为这个类。

在创建的控制类中添加属性。

注意:属性的命名与刚才设置的fx:id一致。

如何使用Javafx的TreeTableView控件构建展示类的树状列表界面?

public class AdminInterface_House_Controller { @FXML private TreeTableView<House> table; @FXML private TreeTableColumn<House, String> houseTree_List; @FXML private TreeTableColumn<House, String> purchaseNumber_List; @FXML private TreeTableColumn<House, String> purchaseDate_List; @FXML private TreeTableColumn<House, String> add_List; @FXML private TreeTableColumn<House, String> houseOwnerID_List; @FXML private TreeTableColumn<House, String> code_List; ...下面的代码省略

在这个类中创建初始化方法。我们将在这个函数中完成完成树表的创建。

@FXML private void initialize() { }

initialize()函数中,进行房屋遍历,每次循环取出一间房屋。每次循环的流程图如下所示:

为了减少initialize()中的代码,我先定义了一个repeatText()方法。这个方法输入一个ObservableList<TreeItem>与String,前者是一个占位房屋列表,后者是一个字符串。

这个函数判断是否存在一个占位房屋的roomNumber变量与输入的字符串相同。
如果存在,则说明输入的字符串重复,该函数输出重复位置。如果不存在,函数输出-1。

private int repeatText(ObservableList<TreeItem<House>> list, String text){ //输出-1代表不重复,输出其他自然数代表重复位置,如0代表与第一个节点重复 int i = -1; House temp; for (TreeItem<House> treeItem : list){ i++; temp = treeItem.getValue(); if (text.equals(temp.getRoomNumber())){ //由于输入的是占位房屋列表,只有roomNumber变量有值。所以只需要判断text是否与roomNumber相同即可。 //重复 return i; } } //不重复 return -1; }

为了便于创建占位房屋,我还在House类中重载了构造函数。

public House(String roomNumber){ this.roomNumber = roomNumber; }

initialize()函数的具体代码较为复杂,具体如下所示。

@FXML private void initialize() { //根节点root TreeItem<House> root = new TreeItem<>( new House("房屋列表")); //绑定root table.setRoot(root); root.setExpanded(true); //遍历房屋列表 for (House house : Structure.getStructure().houseList){ //对于取出的house //取楼盘 //检查重复性 if (repeatText(root.getChildren(), house.getHouseName()) == -1){ //楼盘不重复 //楼盘 //创建占位房屋,作为根节点的子节点 root.getChildren().add(new TreeItem<House>(new House(house.getHouseName()))); //楼号 int pos = root.getChildren().size()-1; //创建占位房屋,作为子节点 root.getChildren().get(pos).setExpanded(true); root.getChildren().get(pos).getChildren().add( new TreeItem<House>(new House(house.getHouseNumber())) ); //楼层 //创建占位房屋,作为子节点 root.getChildren().get(pos).getChildren().get(0).setExpanded(true); root.getChildren().get(pos).getChildren().get(0).getChildren().add( new TreeItem<House>(new House(house.getHouseFloor())) ); //房屋存入 root.getChildren().get(pos).getChildren().get(0).getChildren() .get(0).setExpanded(true); root.getChildren().get(pos).getChildren().get(0).getChildren() .get(0).getChildren().add(new TreeItem<House>(house)); }else { //楼盘重复 //楼盘在root中的位置nameRepeatPos int nameRepeatPos = repeatText(root.getChildren(), house.getHouseName()); //检查楼号重复性 if (repeatText(root.getChildren().get(nameRepeatPos).getChildren(), house.getHouseNumber()) == -1){ //楼盘重复,但楼号不重复 //楼号 root.getChildren().get(nameRepeatPos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().add( new TreeItem<House>(new House(house.getHouseNumber())) ); //楼层 int pos = root.getChildren().get(nameRepeatPos).getChildren().size()-1; root.getChildren().get(nameRepeatPos).getChildren().get(pos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(pos).getChildren().add( new TreeItem<House>(new House(house.getHouseFloor())) ); //房屋存入 root.getChildren().get(nameRepeatPos).getChildren().get(pos).getChildren() .get(0).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(pos).getChildren() .get(0).getChildren().add(new TreeItem<House>(house)); }else { //楼盘重复,楼号重复 //楼号在root中的位置numRepeatPos int numRepeatPos = repeatText(root.getChildren().get(nameRepeatPos).getChildren(), house.getHouseNumber()); //检查楼层重复性 if (repeatText( root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() , house.getHouseFloor()) == -1){ //楼盘重复,楼号重复,楼层不重复 root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren().add( new TreeItem<House>(new House(house.getHouseFloor())) ); //房屋存入 int pos = root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren().size()-1; root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() .get(pos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() .get(pos).getChildren().add(new TreeItem<House>(house)); }else { //楼盘重复,楼号重复,楼层重复 //楼层root中的位置floorRepeatPos int floorRepeatPos = repeatText( root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() , house.getHouseFloor()); //房屋存入 root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() .get(floorRepeatPos).setExpanded(true); root.getChildren().get(nameRepeatPos).getChildren().get(numRepeatPos).getChildren() .get(floorRepeatPos).getChildren().add(new TreeItem<House>(house)); } } } } //向列表中添加条目 houseTree_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new eadOnlyStringWrapper(houseTemp.getValue().getValue().getRoomNumber())); purchaseNumber_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getPurchaseNumber())); code_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getCode())); houseOwnerID_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getHouseOwnerID())); add_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getAdd())); purchaseDate_List.setCellValueFactory((TreeTableColumn.CellDataFeatures<House, String> houseTemp) -> new ReadOnlyStringWrapper(houseTemp.getValue().getValue().getPurchaseDate())); }

最后运行就可以达到树表的效果。

4、未来优化

由于时间比较紧张,这个部分还有很大的优化空间。由于树表计算部分设置在控制器的初始化函数中,因此每次打开房屋页面都要重新计算树表,在房屋数量较多时,这会造成性能浪费。因此,可以在创建每个新房屋时,将该房屋加入树表中,并将这个树表储存起来。每次打开页面时便免去了复杂的计算。