百木园-与人分享,
就是让自己快乐。

【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。
image
在项目中创建一个控制类(我将其命名为AdminInterface_House_Controller),并将刚才创建的页面的fxml文件中的Controller设置为这个类。

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

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

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()函数中,进行房屋遍历,每次循环取出一间房屋。每次循环的流程图如下所示:
image
为了减少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、未来优化

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


来源:https://www.cnblogs.com/Wu-765279087/p/16375601.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » 【Javafx】以树状列表的形式显示类(TreeTableView控件的使用)

相关推荐

  • 暂无文章