如何通知复合材料的孩子收到/失去焦点?

Voj*_*vic 3 java events swt focus hierarchy

我有一个SWT Composite,我需要传递给其他一些代码,这些代码会随意添加子代码.有没有办法通知复合材料的孩子收到并失去了焦点?

为了确保清楚,我无法为每个孩子添加听众,因为我不负责创建这些控件.可以随时添加一个孩子.

Edw*_*son 5

正如Favonius所指出的,您可以挂钩布局事件,例如SWT.Resize确定您何时被绘制并重新计算您的子层次结构,并根据需要添加侦听器.另一种选择只是听取所有焦点事件,只关注那些你感兴趣的控件.

Display过滤器,像听众一样,被告知事件,但过滤器的不同之处在于它们在听众之前运行,他们有机会取消事件,并且他们会被告知所有类型的事件Display.

因此,您可以使用a Filter来检查所有焦点事件,并确定它是否是您感兴趣的事件.例如:

public class MyControl extends Composite
{
    private final Listener focusListener;

    public MyControl(final Composite parent, final int style)
    {
        /* initialize the control... */

        focusListener = new Listener()
        {
            public void handleEvent(Event event)
            {
                if (!(event.widget instanceof Control))
                {
                    return;
                }

                boolean isOurChild = false;
                for (Control c = (Control) event.widget; c != null; c = c.getParent())
                {
                    if (c == container)
                    {
                        isOurChild = true;
                        break;
                    }
                }

                if (isOurChild)
                {
                    System.out.println("Our child is " + (event.type == SWT.FocusIn ? "focused" : "unfocused"));
                }
            }
        };

        getDisplay().addFilter(SWT.FocusIn, focusListener);
        getDisplay().addFilter(SWT.FocusOut, focusListener);

        addDisposeListener(new DisposeListener()
        {
            public void widgetDisposed(DisposeEvent e)
            {
                getDisplay().removeFilter(SWT.FocusIn, focusListener);
                getDisplay().removeFilter(SWT.FocusOut, focusListener);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意有关使用过滤器的警告的javadocDisplay:

出于性能,调试和代码维护的原因,通常应避免使用它们.

显然,您正在考虑任一解决方案中的性能权衡 - 取决于您提供的应用程序类型和用户的工作流程,在调整大小时添加焦点侦听器可能更有意义,或者可能更有意义只需听取所有焦点事件,忽略那些你不感兴趣的事件.