-1

When the multiple trees in the view expanded (Expand the selected tree), the following error is thrown. I couldnot find out what exactly throws this error. this is the stack trace i got after exception,

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)

//Label Provider for that tree public class ViewTreeLabelProvider extends LabelProvider implements 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;
    }
}

My project code base is vast, i could not share it completely. So, i wrote the snippet in the simple way to convey the problem.

Actually, the images are placed in the icons folder and are fetched by AbstractUIPlugin.imageDescriptorFromPlugin(plugin, path), which inturn stores the images in the Image registry.

I also noticed that, this may be due to the limit in the GDI Objects in the Windows registry. After the 10000 GDI objects limit is reached the exception is thrown. By default for Windows 7, GDIProcessHandleQuota value is 10,000. When I googled , I found that, the value can be set to maximum of 65,536.

I have tried to by increasing the GDIProcessHandleQuota from 10,000 to 65,000. Still the same exception is thrown, but after reaching 19,932 GDIObjects. I anticipate that, the problem may be due to improper disposal of GDIObjects and the exception is thrown in the Image.class.

Suggestions please!!

K.Muthu
  • 1,232
  • 1
  • 17
  • 38
  • 2
    From the look of the stack trace you are probably using too many images. Show us the code for the tree particularly the label provider. – greg-449 Nov 07 '14 at 12:56
  • 1
    [Related](http://stackoverflow.com/questions/2018553/swt-no-more-handles). – Baz Nov 07 '14 at 13:01
  • @greg-449 I have added the snippet code for label provider, i have included the getImages() part alone. – K.Muthu Nov 07 '14 at 13:15
  • What does `ClassA.getimage()` ... do? Show us where you actually create the images. And look at the Related link in Baz's comment. – greg-449 Nov 07 '14 at 13:31

1 Answers1

0

In your ClassA.getimage(), ClassB.getimage() ... make sure to not create an image each time ".getimage()" is called, cache it.

    private Image image;

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

Since it seems that you are in an Eclipse environment, better even use "org.eclipse.jface.resource.ImageRegistry". Where "UIPlugin" is your plugin extending "org.eclipse.ui.plugin.AbstractUIPlugin". If you don't have one, create one and add it to your 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;
    }
flavio.donze
  • 7,432
  • 9
  • 58
  • 91