JAVAFX中高级TreeView控件使用教程(用到scenebuilder)

1.TreeView实现效果

TreeView实现效果如下图所示,每个结点包含图片并且右击节点可以显示菜单项

2.菜单类

菜单类负责在右击节点时显示菜单,具体是是实现如下所示,为了节省代码占用行数,省略了一些代码
    private final class TextFieldTreeCellImpl extends TreeCell<String> {

        private TextField textField;// 文本域外观组件对象
        // 上下文菜单对象的创建
        private final ContextMenu addMenu1 = new ContextMenu();
        private final ContextMenu addMenu2 = new ContextMenu();
        private final ContextMenu addMenu3 = new ContextMenu();
        private final ContextMenu addMenu4 = new ContextMenu();
        private final ContextMenu addMenu5 = new ContextMenu();

        public TextFieldTreeCellImpl() {// 构造方法的定义
            // 上下文菜单选项对象的创建
            MenuItem addMenuItem1 = new MenuItem("添加小区节点");
            MenuItem addMenuItem2 = new MenuItem("添加楼号节点");
            MenuItem addMenuItem3 = new MenuItem("添加单元节点");
            MenuItem addMenuItem4 = new MenuItem("添加房间节点");
            MenuItem removeMeunItem1 = new MenuItem("删除小区节点");
            MenuItem removeMeunItem2 = new MenuItem("删除楼号节点");
            MenuItem removeMeunItem3 = new MenuItem("删除单元节点");
            MenuItem removeMeunItem4 = new MenuItem("删除房间节点");
            MenuItem maintain = new MenuItem("维护房间节点");
            //将上下文菜单选项对象添加至上下文菜单对象                                
            addMenu1.getItems().add(addMenuItem1);
            addMenu2.getItems().add(addMenuItem2);
            addMenu3.getItems().add(addMenuItem3);
            addMenu4.getItems().add(addMenuItem4);
            addMenu2.getItems().add(removeMeunItem1);
            addMenu3.getItems().add(removeMeunItem2);
            addMenu4.getItems().add(removeMeunItem3);
            addMenu5.getItems().add(removeMeunItem4);
            addMenu5.getItems().add(maintain);

            //点击上下文菜单选项触发的事件如下
            addMenuItem1.setOnAction((ActionEvent t) -> {
                //以下代码段表示事件触发所执行的代码
                index = 1;
                PopWindow(getTreeItem());
            });// 添加小区节点
        }

        // 获取该Item的名字
        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
        //以下代码负责判断右击节点显示哪个菜单
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                setText(getString());
                setGraphic(getTreeItem().getGraphic());
                if (getTreeItem().getParent() == null) {
                    setContextMenu(addMenu1);
                } else if (getTreeItem().getParent().getParent() == null) {
                    setContextMenu(addMenu2);
                } else if (getTreeItem().getParent().getParent().getParent() == null) {
                    setContextMenu(addMenu3);
                } else if (getTreeItem().getParent().getParent().getParent().getParent() == null) {
                    setContextMenu(addMenu4);
                } else if (getTreeItem().isLeaf()) {
                    setContextMenu(addMenu5);
                } else
                    setContextMenu(null);
            }

        }
    }

}

3.TreeView显示

图片格式要求 像素,位置跟Controller类最好在同一个包,不然不好调用图片。
定义根节点图片
private final Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("12345.png")));
定义分支节点图片
private final Image depIcon1 = new Image(getClass().getResourceAsStream("11.png"));
定义根节点属性
rootItem = new TreeItem<String>("房屋管理", rootIcon);
定义分支节点属性
TreeItem<String> item1 = new TreeItem<>(area.getAreaName(), new ImageView(depIcon1));
完整代码如下所示,值得注意的是最好不要在scenebuilder中建立TreeView,而是在scenebuilder中建立VBox,再将TreeView添加置VBox中去
    private final Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("12345.png")));
    // 创建图片节点
    private final Image depIcon1 = new Image(getClass().getResourceAsStream("11.png"));
    private final Image depIcon2 = new Image(getClass().getResourceAsStream("22.png"));
    private final Image depIcon3 = new Image(getClass().getResourceAsStream("31.png"));
    private final Image depIcon4 = new Image(getClass().getResourceAsStream("41.png"));

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        HouseCatalog.getHouseCatalog().loadJson();
        rootItem = new TreeItem<String>("房屋管理", rootIcon);
        areas = HouseCatalog.getHouseCatalog().getAreas();
        for (Area area : areas) {
            TreeItem<String> item1 = new TreeItem<>(area.getAreaName(), new ImageView(depIcon1));
            rootItem.getChildren().add(item1);
            for (Building building : area.getBuildings()) {
                TreeItem<String> item2 = new TreeItem<>(building.getBuildingName(), new ImageView(depIcon2));
                item1.getChildren().add(item2);
                for (Unit unit : building.getUnits()) {
                    TreeItem<String> item3 = new TreeItem<String>(unit.getUnitname(), new ImageView(depIcon3));
                    item2.getChildren().add(item3);
                    for (House house : unit.getHouses()) {
                        TreeItem<String> item4 = new TreeItem<String>(house.getHouseName(), new ImageView(depIcon4));
                        item3.getChildren().add(item4);
                    }
                }
            }
        }
        TreeView<String> treeView = new TreeView<String>(rootItem);// 创建一个树形结构根节点
        treeView.setCellFactory((TreeView<String> p) -> new TextFieldTreeCellImpl());//设立菜单
        vBox.getChildren().add(treeView);//在vBox中添加TreeView
    }

4.完整代码展示

有缩略,主要关注整体布局
package Controller;

import java.io.IOException;
import java.net.URL;
import java.time.LocalDate;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;

import Model_File.GsonSave;
import Model_Houses.Area;
import Model_Houses.Building;
import Model_Houses.House;
import Model_Houses.HouseCatalog;
import Model_Houses.Unit;
import Model_Service.SeniorService;
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;
/**
 * 房屋管理控制类
 * @author wjz
 *
 */
public class HousingController extends Application implements Initializable {

    // 定义成员变量
    private List<Area> areas;
    private TextField tx1;
    private String controlLine;
    private String controlLine2;
    private String controlLine3;
    private String controlLine4;
    private int index;
    private Stage newStage;
    private TreeItem<String> rootItem;
    private Stage nnewStage;
    private TextField ntx1;
    private TextField ntx2;
    private TextField ntx3;

    @FXML
    private Button button2;

    @FXML
    private DatePicker datePicker;

    @FXML
    private Button right;

    @FXML
    private AnchorPane newPane;

    @FXML
    private Button clearButton;

    @FXML
    private TextField textField2;

    @FXML
    private TextField textField1;

    @FXML
    private TextField textField3;

    @FXML
    private Label label1;

    @FXML
    private Button exit;
    @FXML
    private Label label2;

    @FXML
    private Label label3;

    @FXML
    private Label label4;

    @FXML
    private Button button1;

    @FXML
    private VBox vBox;

    private String line1;

    private String line2;

    private String line3;

    private String line4;

    private House chooseHouse;

 

    /**
     * 开启房屋管理页面
     */
    @Override
    public void start(Stage stage) throws Exception {
        Pane root = (Pane) FXMLLoader.load(getClass().getResource("/View/HousingManagementView.fxml"));
        Scene scene = new Scene(root, 1300, 938);
        stage.setScene(scene);
        stage.setResizable(false);
        stage.setTitle("房屋管理页面");
        stage.show();// TODO Auto-generated method stub

    }

    private final Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("12345.png")));
    // 创建图片节点
    private final Image depIcon1 = new Image(getClass().getResourceAsStream("11.png"));
    private final Image depIcon2 = new Image(getClass().getResourceAsStream("22.png"));
    private final Image depIcon3 = new Image(getClass().getResourceAsStream("31.png"));
    private final Image depIcon4 = new Image(getClass().getResourceAsStream("41.png"));

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        HouseCatalog.getHouseCatalog().loadJson();
        rootItem = new TreeItem<String>("房屋管理", rootIcon);
        areas = HouseCatalog.getHouseCatalog().getAreas();
        for (Area area : areas) {
            TreeItem<String> item1 = new TreeItem<>(area.getAreaName(), new ImageView(depIcon1));
            rootItem.getChildren().add(item1);
            for (Building building : area.getBuildings()) {
                TreeItem<String> item2 = new TreeItem<>(building.getBuildingName(), new ImageView(depIcon2));
                item1.getChildren().add(item2);
                for (Unit unit : building.getUnits()) {
                    TreeItem<String> item3 = new TreeItem<String>(unit.getUnitname(), new ImageView(depIcon3));
                    item2.getChildren().add(item3);
                    for (House house : unit.getHouses()) {
                        TreeItem<String> item4 = new TreeItem<String>(house.getHouseName(), new ImageView(depIcon4));
                        item3.getChildren().add(item4);
                    }
                }
            }
        }
        TreeView<String> treeView = new TreeView<String>(rootItem);// 创建一个树形结构根节点
        treeView.setCellFactory((TreeView<String> p) -> new TextFieldTreeCellImpl());
        vBox.getChildren().add(treeView);
    }

    /**
     * 更新TreeView
     * @param areas
     */
    // 更新TreeView页面
    public void setHouseItems(List<Area> areas) {
        rootItem.getChildren().clear();
        for (Area area : areas) {
            TreeItem<String> item1 = new TreeItem<String>(area.getAreaName());
            rootItem.getChildren().add(item1);
            for (Building building : area.getBuildings()) {
                TreeItem<String> item2 = new TreeItem<String>(building.getBuildingName());
                item1.getChildren().add(item2);
                for (Unit unit : building.getUnits()) {
                    TreeItem<String> item3 = new TreeItem<String>(unit.getUnitname());
                    item2.getChildren().add(item3);
                    for (House house : unit.getHouses()) {
                        TreeItem<String> item4 = new TreeItem<String>(house.getHouseName());
                        item3.getChildren().add(item4);
                    }
                }
            }
        }
    }


    // *********************************使用菜单栏进行修改页面***********************************
    private final class TextFieldTreeCellImpl extends TreeCell<String> {

        private TextField textField;// 文本域外观组件对象
        private final ContextMenu addMenu1 = new ContextMenu();// 上下文菜单对象的创建
        private final ContextMenu addMenu2 = new ContextMenu();
        private final ContextMenu addMenu3 = new ContextMenu();
        private final ContextMenu addMenu4 = new ContextMenu();
        private final ContextMenu addMenu5 = new ContextMenu();

        public TextFieldTreeCellImpl() {// 构造方法的定义
            MenuItem addMenuItem1 = new MenuItem("添加小区节点");
            MenuItem addMenuItem2 = new MenuItem("添加楼号节点");
            MenuItem addMenuItem3 = new MenuItem("添加单元节点");
            MenuItem addMenuItem4 = new MenuItem("添加房间节点");
            MenuItem removeMeunItem1 = new MenuItem("删除小区节点");// 上下文菜单选项对象的创建
            MenuItem removeMeunItem2 = new MenuItem("删除楼号节点");
            MenuItem removeMeunItem3 = new MenuItem("删除单元节点");
            MenuItem removeMeunItem4 = new MenuItem("删除房间节点");
            MenuItem maintain = new MenuItem("维护房间节点");
            addMenu1.getItems().add(addMenuItem1);
            addMenu2.getItems().add(addMenuItem2);
            addMenu3.getItems().add(addMenuItem3);
            addMenu4.getItems().add(addMenuItem4);
            addMenu2.getItems().add(removeMeunItem1);
            addMenu3.getItems().add(removeMeunItem2);
            addMenu4.getItems().add(removeMeunItem3);
            addMenu5.getItems().add(removeMeunItem4);
            addMenu5.getItems().add(maintain);
            addMenuItem1.setOnAction((ActionEvent t) -> {
                index = 1;
                PopWindow(getTreeItem());
            });// 添加小区节点

            addMenuItem2.setOnAction((ActionEvent t) -> {
                controlLine = getTreeItem().getValue();
                index = 2;
                PopWindow(getTreeItem());

            });// 添加楼号节点
            addMenuItem3.setOnAction((ActionEvent t) -> {
                controlLine = getTreeItem().getValue();
                controlLine2 = getTreeItem().getParent().getValue();
                index = 3;
                PopWindow(getTreeItem());

            });// 添加单元节点
            addMenuItem4.setOnAction((ActionEvent t) -> {
                controlLine = getTreeItem().getValue();
                controlLine2 = getTreeItem().getParent().getValue();
                controlLine3 = getTreeItem().getParent().getParent().getValue();
                PopWindowH(getTreeItem());

            });// 添加楼房节点
            removeMeunItem1.setOnAction((ActionEvent t) -> {
                controlLine = getTreeItem().getValue();
                removeArea(controlLine);
                getTreeItem().getParent().getChildren().remove(getTreeItem());
            });// 移除小区节点

            removeMeunItem2.setOnAction((ActionEvent t) -> {
                controlLine = getTreeItem().getValue();
                controlLine2 = getTreeItem().getParent().getValue();
                removeBuilding(controlLine2, controlLine);
                getTreeItem().getParent().getChildren().remove(getTreeItem());
            });// 移除楼号节点

            removeMeunItem3.setOnAction((ActionEvent t) -> {
                controlLine = getTreeItem().getValue();
                controlLine2 = getTreeItem().getParent().getValue();
                controlLine3 = getTreeItem().getParent().getParent().getValue(); 
                removeUnit(controlLine3, controlLine2, controlLine);
                getTreeItem().getParent().getChildren().remove(getTreeItem());
            });// 移除单元节点
            removeMeunItem4.setOnAction((ActionEvent t) -> {
                controlLine = getTreeItem().getValue();
                controlLine2 = getTreeItem().getParent().getValue();
                controlLine3 = getTreeItem().getParent().getParent().getValue();
                controlLine4 = getTreeItem().getParent().getParent().getParent().getValue();
                removeHouse(controlLine, controlLine2, controlLine3, controlLine4);
                getTreeItem().getParent().getChildren().remove(getTreeItem());
            });// 移除房屋节点
            maintain.setOnAction((ActionEvent t) -> {
                controlLine = getTreeItem().getValue();
                controlLine2 = getTreeItem().getParent().getValue();
                controlLine3 = getTreeItem().getParent().getParent().getValue();
                controlLine4 = getTreeItem().getParent().getParent().getParent().getValue();
                line1 = controlLine;
                line2 = controlLine2;
                line3 = controlLine3;
                line4 = controlLine4;
                maintianHouse(controlLine, controlLine2, controlLine3, controlLine4);
            });

            // 维护房间节点
        }

        // 获取该Item的名字
        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }

        /**
         * 更新表格菜单
         */
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                setText(getString());
                setGraphic(getTreeItem().getGraphic());
                if (getTreeItem().getParent() == null) {
                    setContextMenu(addMenu1);
                } else if (getTreeItem().getParent().getParent() == null) {
                    setContextMenu(addMenu2);
                } else if (getTreeItem().getParent().getParent().getParent() == null) {
                    setContextMenu(addMenu3);
                } else if (getTreeItem().getParent().getParent().getParent().getParent() == null) {
                    setContextMenu(addMenu4);
                } else if (getTreeItem().isLeaf()) {
                    setContextMenu(addMenu5);
                } else
                    setContextMenu(null);
            }

        }
    }

}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值