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

Gluon Glisten框架View首次显示时lookup调用失败问题

Gluon Charm Glisten框架View首次加载时Lookup操作失效问题

问题表现

  • 非首页View首次触发onShown生命周期事件时,调用节点lookup/lookupAll方法查询样式类匹配节点会返回空集合
  • 离开该View后再次进入时,相同的lookup逻辑可正常返回目标节点
  • 若将该View设置为应用HOME_VIEW,首次触发onShown事件时lookup可正常执行

最小复现代码

主应用类 MyApplication.java

import static com.gluonhq.charm.glisten.application.AppManager.*;

import javafx.application.Application;
import javafx.stage.Stage;

import com.gluonhq.charm.glisten.application.AppManager;
import com.gpsdemo.view.View1;
import com.gpsdemo.view.View2;

public class MyApplication extends Application {

    AppManager appManager = AppManager.initialize();

    public static final String VIEW1 = HOME_VIEW;
    public static final String VIEW2 = "View2";

    @Override
    public void init() {
        appManager.addViewFactory(VIEW1, View1::get);
        appManager.addViewFactory(VIEW2, View2::get);
    }

    @Override
    public void start(Stage stage) throws Exception {
        appManager.start(stage);
        if (com.gluonhq.attach.util.Platform.isDesktop()) {
            stage.setHeight(600);
            stage.setWidth(360);
            stage.centerOnScreen();
        }
    }

    public static void main(String args[]) {
        launch(args);
    }
}

首页视图 View1.java

import javafx.scene.control.Label;

import com.gluonhq.charm.glisten.control.AppBar;
import com.gluonhq.charm.glisten.mvc.View;
import com.gluonhq.charm.glisten.visual.MaterialDesignIcon;
import com.gpsdemo.MyApplication;

public class View1 extends View {

    private static View1 INSTANCE;

    public static View1 get() {
        return INSTANCE != null ? INSTANCE : (INSTANCE = new View1());
    }

    private View1() {
        setCenter(new Label("Nothing to see here"));
    }

    @Override
    protected void updateAppBar(AppBar appBar) {
        appBar.setTitleText("View1");

        var optionsButton = MaterialDesignIcon.MENU.button(e -> getAppManager().switchView(MyApplication.VIEW2));
        appBar.getActionItems().add(optionsButton);
    }
}

测试问题视图 View2.java

import java.util.Set;

import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Node;

import com.gluonhq.charm.glisten.control.AppBar;
import com.gluonhq.charm.glisten.control.SettingsPane;
import com.gluonhq.charm.glisten.control.settings.DefaultOption;
import com.gluonhq.charm.glisten.mvc.View;
import com.gluonhq.charm.glisten.visual.MaterialDesignIcon;

public class View2 extends View {

    private static View2 INSTANCE;

    public static View2 get() {
        return INSTANCE != null ? INSTANCE : (INSTANCE = new View2());
    }

    private View2() {
        var settingsPane = new SettingsPane();
        var option = new DefaultOption<>("Title", "Description", "Category", new SimpleDoubleProperty(), true);
        settingsPane.getOptions().add(option);
        setCenter(settingsPane);

        setOnShown(e -> {
            System.out.println("On shown");
            Set<Node> lookup = settingsPane.lookupAll(".secondary-graphic");
            System.out.println(lookup);
        });
    }

    @Override
    protected void updateAppBar(AppBar appBar) {
        appBar.setTitleText("View2");

        var backButton = MaterialDesignIcon.ARROW_BACK.button(e -> getAppManager().switchToPreviousView().get());
        appBar.setNavIcon(backButton);
    }
}

复现流程

  1. 启动应用,默认加载展示View1
  2. 点击View1顶部AppBar的菜单按钮切换到View2,首次进入时控制台输出如下:
On shown
[]

此时lookupAll(".secondary-graphic")返回空集合,查询失败
3. 点击View2顶部的返回按钮回到View1,再次切换进入View2,控制台输出如下:

On shown
[HBox@2c8d8a10[styleClass=secondary-graphic]]

此时lookup操作可正常获取到样式类匹配的目标节点

环境信息

<javafx-maven-plugin-version>0.0.8</javafx-maven-plugin-version>
<gluonfx-maven-plugin-version>1.0.14</gluonfx-maven-plugin-version>

<java-version>17</java-version>
<javafx-version>18.0.1</javafx-version>
<charm-version>6.1.0</charm-version>

解决方案

问题本质是onShown事件触发时,非首页加载的View内部复杂控件(如SettingsPane)还未完成皮肤加载、CSS应用和布局渲染,内部子节点尚未挂载到场景图上,直接执行lookup自然无法获取结果。
将lookup逻辑放入Platform.runLater()中执行,延迟到JavaFX下一次渲染脉冲完成、所有节点挂载完毕后再查询,即可保证首次进入View时lookup正常返回结果,修改View2的onShown回调代码如下:

setOnShown(e -> {
    System.out.println("On shown");
    // 延迟到场景完成布局渲染后执行查询
    javafx.application.Platform.runLater(() -> {
        Set<Node> lookup = settingsPane.lookupAll(".secondary-graphic");
        System.out.println(lookup);
        // 此处编写节点后续配置逻辑
    });
});

该方案兼容所有View加载场景,无需修改框架源码,可稳定解决首次加载时lookup失效的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:18:26