如果动作不是由用户触发的,如何禁用SWT事件监听。

5

我注意到 ModifyListener 无论操作是由用户还是系统本身引起都会被触发,例如:

Text t = new Text(shell, SWT.BORDER);
t.addModifyListener(new TModifyListener());

...............................................

private class TModifyListener implements ModifyListener
{

    @Override
    public void modifyText(ModifyEvent event)
    {

        Text text = (Text) event.widget;
        t.setText(process(text.getText()));
    }
}

这将导致无限循环并使程序崩溃。你们有没有想过如何在事件由系统生成时禁用事件监听,而在事件由用户引起时启用它?

当然,这将导致你的堆栈溢出。你为什么要写这段代码?你想要实现什么目标?你是在解决模型与用户界面绑定的问题吗? - andyczerwonka
是的,我正在尝试自己实现Presentation-Model架构,特别是我正在尝试实现类似于MS Word中拥有的自动校正功能。 - janetsmith
2个回答

2

你能在监听器中设置一个ThreadLocal,在重新进入时检查它吗?

编辑:事实上,它甚至不需要是ThreadLocal,因为SWT是单线程的。只需在监听器上设置一个布尔字段。

private class TModifyListener implements ModifyListener {

    private boolean _setting;

    @Override
    public void modifyText(ModifyEvent event)
    {
            if(!_setting) {
                _setting = true;
                try {
                    Text text = (Text) event.widget;
                    t.setText(process(text.getText()));
                } finally {
                    _setting = false;
                }
            }
    }
}

只要事件广播按顺序运行,这种方法就有效。我担心的是事件广播可能以异步/并发方式运行。那可能会引起问题。 - janetsmith
你可以将 _setting 的主体内容放在一个 synchronized 中,以避免这个问题。 - Paul Lammertsma

1

我不知道 SWT 但是...

如果 process 是幂等的,那么或许你可以只在 setTextgetText 不同的情况下才调用 setText

另一个选项是在第一个回调中设置小部件的某些属性,然后在第二个回调中查询并取消设置,从而不调用 setText


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接