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

如何在GWT应用调试模式下显示组件的创建类归属信息

解决方案:追踪Widget创建类并自动附加调试Tooltip

要实现调试模式下鼠标悬停GWT组件时显示创建类,同时避免逐个文件修改代码,你可以按照以下步骤操作:

1. 创建调试元数据工具类

这个类负责记录Widget的创建类,并生成调试Tooltip:

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Widget;
import com.gwtext.client.widgets.Tooltip;

public class DebugWidgetUtils {

    // 记录Widget的创建类到自定义数据中
    public static void trackCreationClass(Widget widget) {
        if (!GWT.isDebugMode()) {
            return; // 生产模式下不执行
        }

        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        // 遍历堆栈,过滤GWT内部类和工具类,找到第一个用户创建类
        for (StackTraceElement element : stackTrace) {
            String className = element.getClassName();
            if (!className.startsWith("com.google.gwt.") &&
                !className.startsWith("com.gwtext.client.") &&
                !className.equals(DebugWidgetUtils.class.getName())) {
                widget.setData("creationClass", className);
                break;
            }
        }
    }

    // 给Widget附加调试Tooltip
    public static void attachDebugTooltip(Widget widget) {
        if (!GWT.isDebugMode()) {
            return;
        }

        String creationClass = (String) widget.getData("creationClass");
        // 兼容未提前追踪的情况(尽量补全)
        if (creationClass == null) {
            trackCreationClass(widget);
            creationClass = (String) widget.getData("creationClass");
        }

        // 构建Tooltip内容
        StringBuilder tooltipContent = new StringBuilder();
        tooltipContent.append("Parent: ").append(widget.getClass().getSuperclass().getName()).append("\n");
        tooltipContent.append("This: ").append(widget.getClass().getName()).append("\n");
        tooltipContent.append("Object created in: ").append(creationClass != null ? creationClass : "Unknown");

        // 初始化并绑定Tooltip
        Tooltip tooltip = new Tooltip();
        tooltip.setText(tooltipContent.toString());
        tooltip.applyTo(widget.getElement());
        // 标记已添加Tooltip,避免重复绑定
        widget.setData("debugTooltipAttached", true);
    }
}

2. 实现Widget工厂类(统一创建入口)

通过工厂类封装Widget的创建逻辑,自动调用调试工具类的方法,避免逐个修改创建代码:

import com.google.gwt.user.client.ui.Widget;

public class WidgetFactory {

    @SuppressWarnings("unchecked")
    public static <T extends Widget> T create(Class<T> widgetClass) {
        try {
            // 实例化Widget
            T widget = widgetClass.getDeclaredConstructor().newInstance();
            // 自动追踪创建类并附加Tooltip
            DebugWidgetUtils.trackCreationClass(widget);
            DebugWidgetUtils.attachDebugTooltip(widget);
            return widget;
        } catch (Exception e) {
            throw new RuntimeException("Failed to instantiate widget: " + widgetClass.getName(), e);
        }
    }
}

3. 替换现有代码中的Widget创建方式

使用IDE的全局替换功能,将所有new XXX()(比如new TextField<>()、new Grid())替换为WidgetFactory.create(XXX.class)。例如:

原代码:

TextField<String> text = new TextField<String>();
Grid g = new Grid();

替换后:

TextField<String> text = WidgetFactory.create(TextField.class);
Grid g = WidgetFactory.create(Grid.class);

这样只需一次全局替换,就能让所有Widget自动拥有调试Tooltip,无需逐个文件修改。

4. 验证效果

启动应用并添加?debug=true参数访问页面,鼠标悬停在TextField或Grid组件上,Tooltip将显示:

Parent: com.gwtext.client.widgets.BoxComponent
This: com.gwtext.client.widgets.form.TextField
Object created in: com.google.gwt.sample.stockwatcher.client.StockWatcher

关键注意点

  • 性能影响:由于GWT.isDebugMode()是编译期判断,生产模式下所有调试代码会被自动移除,不会影响应用性能。
  • 堆栈过滤:堆栈遍历中过滤了GWT和GWText的内部类,确保获取的是用户代码中的创建类。
  • 兼容性:支持所有继承自Widget的组件,包括GWT原生和GWText的组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:23:07