【问题标题】:Unknown Error: SWT Error: No more handles未知错误:SWT 错误:没有更多句柄
【发布时间】:2015-01-04 06:31:38
【问题描述】:

当视图中的多棵树展开(Expand the selected tree)时,会抛出以下错误。 我无法找出究竟是什么引发了这个错误。这是我在异常后得到的堆栈跟踪,

org.eclipse.swt.SWTError: No more handles
    at org.eclipse.swt.SWT.error(SWT.java:4109)
    at org.eclipse.swt.SWT.error(SWT.java:3998)
    at org.eclipse.swt.SWT.error(SWT.java:3969)
    at org.eclipse.swt.widgets.Display.internal_new_GC(Display.java:2589)
    at org.eclipse.swt.graphics.Image.getImageData(Image.java:1371)
    at org.eclipse.swt.internal.ImageList.set(ImageList.java:401)
    at org.eclipse.swt.internal.ImageList.add(ImageList.java:66)
    at org.eclipse.swt.widgets.Tree.imageIndex(Tree.java:3636)
    at org.eclipse.swt.widgets.TreeItem.setImage(TreeItem.java:1686)
    at org.eclipse.jface.viewers.TreeViewerRow.setImage(TreeViewerRow.java:166)
    at org.eclipse.jface.viewers.ViewerCell.setImage(ViewerCell.java:169)
    at org.eclipse.jface.viewers.WrappedViewerLabelProvider.update(WrappedViewerLabelProvider.java:166)
    at org.eclipse.jface.viewers.ViewerColumn.refresh(ViewerColumn.java:152)
    at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:934)
    at org.eclipse.jface.viewers.AbstractTreeViewer$UpdateItemSafeRunnable.run(AbstractTreeViewer.java:102)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49)
    at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
    at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:1014)
    at org.eclipse.jface.viewers.StructuredViewer$UpdateItemSafeRunnable.run(StructuredViewer.java:481)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49)
    at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
    at org.eclipse.jface.viewers.StructuredViewer.updateItem(StructuredViewer.java:2141)
    at org.eclipse.jface.viewers.AbstractTreeViewer.createTreeItem(AbstractTreeViewer.java:829)
    at org.eclipse.jface.viewers.AbstractTreeViewer$1.run(AbstractTreeViewer.java:804)
    at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
    at org.eclipse.jface.viewers.AbstractTreeViewer.createChildren(AbstractTreeViewer.java:778)
    at org.eclipse.jface.viewers.TreeViewer.createChildren(TreeViewer.java:644)
    at org.eclipse.jface.viewers.AbstractTreeViewer.internalExpandToLevel(AbstractTreeViewer.java:1714)
    at org.eclipse.jface.viewers.AbstractTreeViewer.internalExpandToLevel(AbstractTreeViewer.java:1724)
    at org.eclipse.jface.viewers.AbstractTreeViewer.internalExpandToLevel(AbstractTreeViewer.java:1724)
    at org.eclipse.jface.viewers.AbstractTreeViewer.internalExpandToLevel(AbstractTreeViewer.java:1724)
    at org.eclipse.jface.viewers.AbstractTreeViewer.internalExpandToLevel(AbstractTreeViewer.java:1724)
    at org.eclipse.jface.viewers.AbstractTreeViewer.expandToLevel(AbstractTreeViewer.java:1056)
    at org.eclipse.jface.viewers.AbstractTreeViewer.expandToLevel(AbstractTreeViewer.java:1037)
    at org.eclipse.jface.viewers.AbstractTreeViewer.expandAll(AbstractTreeViewer.java:1026)
    at com.rockwellcollins.rccase.tarbuilder.actions.ExpandAllAction.run(ExpandAllAction.java:44)
    at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
    at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
    at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
    at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
    at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at com.rockwellcollins.rccase.Application.start(Application.java:74)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:620)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1384)

//该树的标签提供程序 公共类 ViewTreeLabelProvider 扩展了 LabelProvider 实现 IColorProvider、IBaseLabelProvider、IFontProvider{

@Override
public Image getImage(Object element) {

    if (element instanceof EObject) {
        return aa.getImages(element);
    }
    return super.getImage(element);
    }
}


// for loading image 
public class aa {
    public static Image getImages(Object element) {
        if (element instanceof ClassA) {
            return ClassA.getimage();
        } else if (element instanceof ClassB) {
            return ClassB.getimage();
        } else if (element instanceof ClassC) {
            return ClassC.getimage();
        }  else if (element instanceof ClassD) {
            return ClassD.getimage();
        }
        return null;
    }
}

我的项目代码库很大,我无法完全分享。所以,我用简单的方式写了sn-p来表达问题。

实际上,图片是放在icons文件夹中,由AbstractUIPlugin.imageDescriptorFromPlugin(plugin, path)获取,然后将图片存储在Image registry中。

我还注意到,这可能是由于 Windows 注册表中 GDI 对象的限制。 达到 10000 个 GDI 对象限制后,将引发异常。 默认情况下,对于 Windows 7,GDIProcessHandleQuota 值为 10,000。 google了一下,发现这个值可以设置为最大65536。

我尝试将 GDIProcessHandleQuota 从 10,000 增加到 65,000。仍然抛出相同的异常,但在达到 19,932 个 GDIObject 之后。 我预计,问题可能是由于 GDIObjects 的不当处置和 Image.class 中引发的异常。

请给点建议!!

【问题讨论】:

  • 从堆栈跟踪的外观来看,您可能使用了太多图像。向我们展示树的代码,尤其是标签提供者。
  • @greg-449 我已经为标签提供者添加了 sn-p 代码,我已经单独包含了 getImages() 部分。
  • ClassA.getimage() ... 是做什么的?向我们展示您实际创建图像的位置。并查看 Baz 评论中的相关链接。

标签: java swt rcp


【解决方案1】:

在您的 ClassA.getimage()、ClassB.getimage() ... 确保不要在每次调用“.getimage()”时创建图像,缓存它。

    private Image image;

    public Image getImage() {
        if ( image == null) {
            image = new Image(Display.getDefault(), "");
        }
        return image;
    }

由于您似乎处于 Eclipse 环境中,最好使用“org.eclipse.jface.resource.ImageRegistry”。 其中“UIPlugin”是扩展“org.eclipse.ui.plugin.AbstractUIPlugin”的插件。 如果您没有,请创建一个并将其添加到您的 MANIFEST.MF(Bundle-Activator: YOURCLASS)。

    public Image getImage() {
        String key = getClass().getName();
        ImageRegistry imageRegistry = UIPlugin.getDefault().getImageRegistry();
        Image image = imageRegistry.get(key);
        if (image == null) {
            image = new Image(Display.getDefault(), "");
            imageRegistry.put(key, image);
        }
        return image;
    }

【讨论】:

    猜你喜欢
    • 2011-10-31
    • 2016-10-17
    • 1970-01-01
    • 2013-11-25
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多