You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX TabPane初始化时仅含1个Tab且Tab为空,调用方法触发空指针异常

问题

场景刚打开时,FXML里定义的TabPane只认默认选中的那个Tab,调用tabpane.getTabs().size()一直返回1,其他Tab调用getTabPane()全是null,执行权限控制代码直接抛空指针。切过Tab之后功能就正常,但我得在切换前就把Tab权限控制好。

代码片段

public TabPane tabpane;
public Tab sellScreenTab;
public Tab buyScreenTab;
public Tab stockControlTab;
public Tab logTab;
public Tab userTab;
public Tab statisticsTab;


public void editTabsForUsers(){
    System.out.println(tabpane.getTabs().size());
    if (!Session.user.sellScreenPerm){
        sellScreenTab.getTabPane().getTabs().remove(sellScreenTab);
    }if (!Session.user.entryScreenPerm){
        buyScreenTab.getTabPane().getTabs().remove(buyScreenTab);
    }if (!Session.user.historyScreenPerm){
        logTab.getTabPane().getTabs().remove(logTab);
    }if (!Session.user.statsScreenPerm){
        statisticsTab.getTabPane().getTabs().remove(statisticsTab);
    }if (!Session.user.trackStockScreenPerm){
        stockControlTab.getTabPane().getTabs().remove(stockControlTab);
    }if (!Session.user.usersScreenPerm){
        userTab.getTabPane().getTabs().remove(userTab);
    }
}

抛出的异常

Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.control.TabPane.getTabs()" because the return value of "javafx.scene.control.Tab.getTabPane()" is null
原因

JavaFX为了优化性能,场景初始化时只会加载默认选中的Tab,其他没被选中的Tab还没和TabPane建立关联,也没被加入到TabPane的tabs列表里,所以这些Tab的getTabPane()返回null,tabpane.getTabs().size()自然只有1。

解决办法

别通过Tab自己的getTabPane()去拿列表,直接操作TabPane的tabs集合就行,而且操作前先判断Tab是否在集合里,避免报错。

修改后的editTabsForUsers():

public void editTabsForUsers(){
    if (!Session.user.sellScreenPerm && tabpane.getTabs().contains(sellScreenTab)){
        tabpane.getTabs().remove(sellScreenTab);
    }
    if (!Session.user.entryScreenPerm && tabpane.getTabs().contains(buyScreenTab)){
        tabpane.getTabs().remove(buyScreenTab);
    }
    if (!Session.user.historyScreenPerm && tabpane.getTabs().contains(logTab)){
        tabpane.getTabs().remove(logTab);
    }
    if (!Session.user.statsScreenPerm && tabpane.getTabs().contains(statisticsTab)){
        tabpane.getTabs().remove(statisticsTab);
    }
    if (!Session.user.trackStockScreenPerm && tabpane.getTabs().contains(stockControlTab)){
        tabpane.getTabs().remove(stockControlTab);
    }
    if (!Session.user.usersScreenPerm && tabpane.getTabs().contains(userTab)){
        tabpane.getTabs().remove(userTab);
    }
}

另外,要在场景初始化完成后调用这个方法,比如在控制器的initialize()方法里执行:

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    editTabsForUsers();
}

要是发现有些Tab没被自动加到TabPane的列表里,就手动加进去(确保FXML里的Tab都已经绑定到控制器的对应字段):

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    tabpane.getTabs().addAll(sellScreenTab, buyScreenTab, stockControlTab, logTab, userTab, statisticsTab);
    editTabsForUsers();
}

内容的提问来源于stack exchange,提问作者rotroq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:54:25