JavaFX中如何比较Node对象与FXMLLoader.load返回的Node值
问题根因
你的代码匹配失败的核心原因非常明确:
- 每次调用
FXMLLoader.load()都会创建全新的Node对象实例,哪怕加载的是同一个FXML路径,新生成的对象和已经挂载在BorderPane上的原有节点是完全独立的内存对象 - Node类默认的
equals()方法是直接比较两个对象的内存地址,所以你拿新创建的节点和正在显示的节点比对,永远会返回false,不可能匹配成功 - 额外代码问题:你在
getPageNo()里每次调用都重复加载4份FXML,属于无意义的IO+内存开销,频繁调用还会造成界面卡顿;另外你next()方法里取当前页的代码bp.getCenter().getParent()是错的,bp.getCenter()本身就是你设置的中心页面节点,再调getParent()拿到的是BorderPane本身,根本不是你加载的页面。
可行解决方案
方案1:维护页码成员变量(优先推荐,逻辑最简单性能最好)
完全不需要做节点比对,直接在Controller中定义一个整型成员变量记录当前页码,每次切换页面时同步更新变量值即可。
- 在Controller类中添加成员变量,初始值和你默认加载的第一页对应:
private int currentPageNo = 1; - 改写
next()方法,直接基于变量判断跳转逻辑,不需要调用原有的错误getPageNo()逻辑:@FXML private void next(ActionEvent event) { switch (currentPageNo) { case 1: loadPage2(); currentPageNo = 2; break; case 2: loadPage3(); currentPageNo = 3; break; case 3: loadPage4(); currentPageNo = 4; break; default: // 最后一页的自定义逻辑,比如禁用下一步按钮、提示已到末尾等 break; } }
所有主动切换页面的逻辑(比如上一步按钮、首页默认加载),只要修改了bp的中心节点,同步更新currentPageNo的值即可,逻辑简单没有额外开销。
方案2:给节点绑定自定义页码属性(适合需要从节点本身读取页码的场景)
如果你不想维护额外变量,希望直接从当前显示的节点上获取页码,可以在加载页面时给节点打上自定义属性标记,后续直接读取属性值即可,不需要重复加载FXML。
- 改造各个页面加载方法,在把节点设置到BorderPane之前给节点存页码属性:
private void loadPage1() throws IOException { Parent page = FXMLLoader.load(getClass().getResource("/View_FXMLGUI/AddStudent1FXML.fxml")); // 给节点绑定自定义属性存页码 page.getProperties().put("pageNum", 1); bp.setCenter(page); } // loadPage2、loadPage3、loadPage4写法一致,分别给pageNum赋值2、3、4即可 - 重写
getPageNo()方法,直接读取节点上的属性,不需要重复加载FXML:int getPageNo(Node currentNode) { Object pageNum = currentNode.getProperties().get("pageNum"); return pageNum != null ? (int) pageNum : 0; } - 修正
next()里取当前节点的错误代码:Parent currentPage = (Parent) bp.getCenter();
内容的提问来源于stack exchange,提问作者Anuj Kumar
相关产品推荐
相关产品推荐

