我今天的问题涉及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
}
});
答案 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);