【问题标题】:org.eclipse.swt.SWTException: "Widget is disposed" from table refreshorg.eclipse.swt.SWTException:表刷新中的“小部件已处理”
【发布时间】:2013-08-23 18:43:59
【问题描述】:

该应用程序是在 Windows 7 上运行的基于 Eclipse 3.6 的 RCP(即 jface 版本 3.5.2)。

我有一个自定义 View 类,其中包含 TableViewer 并在其上调用 refresh()。有时,但不经常会导致下面的堆栈跟踪。它是从 UI 线程中调用的。我怀疑问题出在将支持列表更改为表的其他代码上,但是任何执行此操作的代码也在 syncExec 或 asyncExec 方法中运行,所以我不明白它如何可能是更改之间的同步问题表项的数量和查看器的刷新。

有什么想法可以防止这种情况发生吗?

!ENTRY org.eclipse.jface 4 2 2010-10-20 09:22:06.140 !MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.jface". !STACK 0 org.eclipse.swt.SWTException: Widget is disposed 
at org.eclipse.swt.SWT.error(SWT.java:3884) at org.eclipse.swt.SWT.error(SWT.java:3799) 
at org.eclipse.swt.SWT.error(SWT.java:3770) at org.eclipse.swt.widgets.Widget.error(Widget.java:463) 
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:336) 
at org.eclipse.swt.widgets.Widget.getData(Widget.java:521) 
at org.eclipse.jface.viewers.AbstractTableViewer.setSelectionToWidget(AbstractTableViewer.java:921) 
at org.eclipse.jface.viewers.StructuredViewer.setSelectionToWidget(StructuredViewer.java:1711) 
at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1399) 
at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1353) 
at org.eclipse.jface.viewers.StructuredViewer.refresh(StructuredViewer.java:1455) 
at org.eclipse.jface.viewers.ColumnViewer.refresh(ColumnViewer.java:537) 
at org.eclipse.jface.viewers.StructuredViewer.refresh(StructuredViewer.java:1414)
... 
at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:179)

【问题讨论】:

  • 您的意思是“将支持列表更改为表”是对底层 SWT-Table 组件的直接访问,还是它们也在查看器上工作?一个 sn-p 会很有帮助

标签: java swt eclipse-rcp jface


【解决方案1】:

似乎在查看器被处置(关闭?)之后调用了 refresh() 方法。您可以通过检查来避免此异常:

public void refresh() {
   if (viewer != null && !viewer.getControl().isDisposed()) {
      // Actual refresh code
   }
}

【讨论】:

  • 这只是一种解决方法,您基本上必须在任何地方使用它。抛出此错误,如果某些已处理的小部件没有被垃圾收集,当小部件在某处用作侦听器并且在被处理后未取消注册时,我经常收到此错误。 spektom 提出的解决方案只是在一个地方避免了这个问题,并没有真正解决它,我会用它作为最后一个实例。首先,我会检查您的小部件是否在处理后的某处被引用。
【解决方案2】:

尝试像这样使用 display.isDisposed()。

    shell.getDisplay().asyncExec(new Runnable()
    {
        @Override
        public void run ()
        {
            if(!display.isDisposed() && !disposing)
            {
                              //you source code
            }
        }
    });

但请记住 isDisposed() 返回 true 然后处理结束。这就是为什么你应该使用标志

处置=真;

display.dispose();

处置=假;

【讨论】:

    【解决方案3】:

    只需创建一个新的工作空间。导入您的项目。它对我有用。 :)

    【讨论】:

      猜你喜欢
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 2022-01-19
      • 2018-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多