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

如何获知控件可见状态变化?父控件影响下子控件无事件问题咨询

SWT控件随父控件可见性变化时的事件监听问题

问题原因

SWT中SWT.Show和SWT.Hide事件仅在控件自身被调用setVisible()方法时才会触发。当父控件的可见性改变时,子控件的实际可见状态(通过isVisible()获取)会同步变化,但不会自动触发子控件的Show/Hide事件,这就是你代码中无法获取Button的Show/Hide事件的核心原因。

解决方案

方法1:父控件事件中手动触发子控件事件

在父控件的Show/Hide监听逻辑里,手动调用子控件的notifyListeners()方法发送对应事件,直接关联父控件状态变化与子控件事件:

Display display = Display.getDefault();
Shell shell = new Shell(display);
shell.setSize(400, 600);
shell.setLayout(new FillLayout(SWT.VERTICAL));

Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new FillLayout());
Button test = new Button(composite, SWT.NONE);
test.setText("test");

composite.addListener(SWT.Show, e -> {
    System.out.println("Composite Show");
    // 手动给子Button发送Show事件
    test.notifyListeners(SWT.Show, new Event());
});
composite.addListener(SWT.Hide, e -> {
    System.out.println("Composite Hide");
    // 手动给子Button发送Hide事件
    test.notifyListeners(SWT.Hide, new Event());
});

test.addListener(SWT.Show, e -> System.out.println("Button Show"));
test.addListener(SWT.Hide, e -> System.out.println("Button Hide"));

Button btn = new Button(shell, SWT.TOGGLE);
btn.setText("Show / Hide");
btn.addListener(SWT.Selection, e -> {
    composite.setVisible(btn.getSelection());
    System.out.println(test.isVisible());
});

shell.open();
while (!shell.isDisposed()) {
    if (!display.readAndDispatch()) {
        display.sleep();
    }
}

方法2:递归触发所有子控件事件(适合多层嵌套场景)

如果控件存在多层嵌套结构,可以写一个递归工具方法,遍历父控件下所有子控件并触发对应事件,无需逐个手动关联:

Display display = Display.getDefault();
Shell shell = new Shell(display);
shell.setSize(400, 600);
shell.setLayout(new FillLayout(SWT.VERTICAL));

Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new FillLayout());
Button test = new Button(composite, SWT.NONE);
test.setText("test");

// 递归触发控件及其所有子控件的可见性事件
private static void fireVisibilityEvent(Control control, int eventType) {
    control.notifyListeners(eventType, new Event());
    if (control instanceof Composite) {
        for (Control child : ((Composite) control).getChildren()) {
            fireVisibilityEvent(child, eventType);
        }
    }
}

composite.addListener(SWT.Show, e -> {
    System.out.println("Composite Show");
    fireVisibilityEvent(composite, SWT.Show);
});
composite.addListener(SWT.Hide, e -> {
    System.out.println("Composite Hide");
    fireVisibilityEvent(composite, SWT.Hide);
});

test.addListener(SWT.Show, e -> System.out.println("Button Show"));
test.addListener(SWT.Hide, e -> System.out.println("Button Hide"));

Button btn = new Button(shell, SWT.TOGGLE);
btn.setText("Show / Hide");
btn.addListener(SWT.Selection, e -> {
    composite.setVisible(btn.getSelection());
    System.out.println(test.isVisible());
});

shell.open();
while (!shell.isDisposed()) {
    if (!display.readAndDispatch()) {
        display.sleep();
    }
}

补充说明

如果不需要严格依赖SWT的Show/Hide事件,也可以通过监听父控件的可见性变化,结合子控件的isVisible()方法判断状态后处理逻辑,但手动触发事件的方式更贴合SWT的事件驱动设计模式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:54:56