防止侦听器触发自身

时间:2013-04-16 15:56:56

标签: java swt listener

我今天的问题涉及JFace TreeViewer Composite中的简单争用。我正在尝试将ControlListener附加到树的列中以强制执行最小宽度。要做到这一点,我每次都会看到列的大小调整,如果新的宽度太小,我会将最小值强加到它上面。

这是一个GUI问题,但实际上它可能会在具有修改侦听器的任何Java环境中发生。我想也许你们中的一些Java怪人可能会玩得很开心。

    public static void getSizeControlListener(final TreeColumn column, final int minSize) {
        column.addControlListener(new ControlListener() {
            @Override
            public void controlMoved(ControlEvent e) {}

            @Override
            public void controlResized(ControlEvent e) {
                if(column.getWidth()<minSize) {
                    column.setWidth(minSize);
                }
            }
    });

一个有效的解决方案是添加一个在入口处设置的标志,任何嵌套的调用都可以引用该标志,并在必要时立即退出。它有效,但它又脏又丑。

    public static void getSizeControlListener(final TreeColumn column, final int minSize) {
        column.addControlListener(new ControlListener() {

            private boolean isRunning;

            @Override
            public void controlMoved(ControlEvent e) {}

            @Override
            public void controlResized(ControlEvent e) {
                if(isRunning)
                    return;
                isRunning = true;
                if(column.getWidth()<minSize) {
                    column.setWidth(minSize);
                }
                isRunning = false
            }
    });

2 个答案:

答案 0 :(得分:1)

带有标志的解决方案完全正常,我们会定期使用此模式阻止通知级联
发生这种级联的一个示例是在MVC中同步模型视图状态时。使用这样的标志允许我们通过双向同步实现无级联单向更新。

与您的实现的唯一区别是我们使用try..finally来确保标志始终被重置(同样发生异常时):

if (updating) {
    return;
}
try {
   updating=true;

   // do stuff

} finally {
   updating=false;
}

答案 1 :(得分:0)

我认为你应该将代码放在org.eclipse.swt.widgets.Display.asyncExec(Runnable)

column.setWidth(minSize);