WARNING: Prevented recursive attempt to activate part org.eclipse.ui.views.PropertySheet while still in the middle of activating part VV
代码的错误处:
if (partBeingActivated != null) {
if (partBeingActivated.getPart(false) != newPart) {
WorkbenchPlugin.log(new RuntimeException(NLS.bind(
"WARNING: Prevented recursive attempt to activate part {0} while still in the middle of activating part {1}", //$NON-NLS-1$
getId(newPart), getId(partBeingActivated))));
}
return;
}
解决办法:
在你的view/edior中添加
@Override
public void setFocus() {
这里不能为空,只要为空就会出现那种错误。
界面中的控件.setFocus();
}
原因:
通过对代码的调试:
没选择一次part
WorkbenchPage.setActivePart 方法会调用三次,
三次调用都是内部调用,只有第三次调用完之后才会执行。
setActivePart 方法最后的
finally {
partBeingActivated = null;
Object blame = newPart == null ? (Object)this : newPart;
UIStats.end(UIStats.ACTIVATE_PART, blame, label);
}
这样partBeingActivated的值才为null,
三次调用的流程为:
选择part,出发setActivePart方法,activatePart(newPart); 第一次
setActivePart方法内部又调用自身一次 第二次
第二次的时候就直接return,所以没有进入try里面,不会执行finally
if (partBeingActivated != null) {
if (partBeingActivated.getPart(false) != newPart) {
WorkbenchPlugin.log(new RuntimeException(NLS.bind(
"WARNING: Prevented recursive attempt to activate part {0} while still in the middle of activating part {1}", //$NON-NLS-1$
getId(newPart), getId(partBeingActivated))));
}
return;
}
就在这里return了。
第三次 在 PartPane中 ,这里也是没有进入try里面,不会执行finally
public void setFocus() {
requestActivation(); 这里面已经调用了两次
IWorkbenchPart part = partReference.getPart(true);
if (part != null) {
Control control = getControl();
if (!SwtUtil.isFocusAncestor(control)) {
// First try to call part.setFocus
part.setFocus(); 这里有去重新调用了一次。如何方法体为空,就不会去调用。
关键是这里如果你没有设置setFocus,就会被PropertySheet所调用,这个时候就会报错了。。
}
}
这里是最上层的调用,在这个方法最好结束时,才会去去调用
finally {
partBeingActivated = null;
Object blame = newPart == null ? (Object)this : newPart;
UIStats.end(UIStats.ACTIVATE_PART, blame, label);
}
}
主要就是把这个方法看明白,这问题就清楚了。
private void setActivePart(IWorkbenchPart newPart, boolean force) {
// Optimize it. 如何选择同样的,直接return
if (!force && (getActivePart() == newPart)) {
return;
}
如果准备打开的part为不为null,直接return
if (partBeingActivated != null) {
如果准备打开的和将要打开的不是同一个part,报错。
if (partBeingActivated.getPart(false) != newPart) {
WorkbenchPlugin.log(new RuntimeException(NLS.bind(
"WARNING: Prevented recursive attempt to activate part {0} while still in the middle of activating part {1}", //$NON-NLS-1$
getId(newPart), getId(partBeingActivated))));
}
return;
}
//下面的代码没有准备打开的part时,才去执行。
。。。。。
初始化准备要打开的part
partBeingActivated = realPartRef;
重新调用这个方法。,这次调用就会直接return
activatePart(newPart);
actionSwitcher.updateActivePart(newPart);
partList.setActivePart(partref);
} finally {
partBeingActivated = null;
Object blame = newPart == null ? (Object)this : newPart;
UIStats.end(UIStats.ACTIVATE_PART, blame, label);
}
}
模拟类
public class Test {
public static void main(String[] args) {
test2();
}
private static int count=0;
private static void test2()
{
test(-1);
}
private static void test(int i)
{
count++;
System.out.println("第"+count+"次");
if(i==1)
return;
try {
i=1;
test(1);
test(1);
} catch (Exception e) {
// TODO: handle exception
}finally{
System.out.println("finally");
}
}
}
执行结果
第1次
第2次
第3次 第三次 有可能被propertysheet调用了。
finally