Skip to content

SWTError: "Item not added" in Image.setImageMetadataForHandle(ImageHandle imageMetadata, Integer zoom) #2188

@estepper

Description

@estepper

Describe the bug
Since 2025-06, when I try to display an image that was created via new Image(display, sourceImage, SWT.IMAGE_DISABLE) from a sourceImage = new Image(display, new ByteArrayInputStream(bytes)), I get the following SWTError:

Exception in thread "main" org.eclipse.swt.SWTError: Item not added
	at org.eclipse.swt.SWT.error(SWT.java:4970)
	at org.eclipse.swt.SWT.error(SWT.java:4860)
	at org.eclipse.swt.SWT.error(SWT.java:4831)
	at org.eclipse.swt.graphics.Image.setImageMetadataForHandle(Image.java:1553)
	at org.eclipse.swt.graphics.Image$ImageHandle.<init>(Image.java:2619)
	at org.eclipse.swt.graphics.Image.initBitmapHandle(Image.java:1581)
	at org.eclipse.swt.graphics.Image.init(Image.java:1672)
	at org.eclipse.swt.graphics.Image$AbstractImageProviderWrapper.newImageHandle(Image.java:1911)
	at org.eclipse.swt.graphics.Image$ImageFromImageDataProviderWrapper.initializeHandleFromSource(Image.java:1990)
	at org.eclipse.swt.graphics.Image$ImageFromImageDataProviderWrapper.newImageHandle(Image.java:1983)
	at org.eclipse.swt.graphics.Image.getImageMetadata(Image.java:785)
	at org.eclipse.swt.graphics.Image.win32_getHandle(Image.java:809)
	at org.eclipse.swt.graphics.GC.drawImage(GC.java:1113)
	at org.eclipse.swt.graphics.GC.drawImage(GC.java:1052)
	at org.eclipse.swt.graphics.GC.drawImageInPixels(GC.java:948)
	at org.eclipse.swt.graphics.GC.drawImage(GC.java:941)
	at org.eclipse.swt.widgets.Label.wmDrawChildImage(Label.java:570)
	at org.eclipse.swt.widgets.Label.wmDrawChild(Label.java:617)
	at org.eclipse.swt.widgets.Control.WM_DRAWITEM(Control.java:5006)
	at org.eclipse.swt.widgets.Control.windowProc(Control.java:4793)
	at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:336)
	at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1494)
	at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2387)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:5106)
	at org.eclipse.swt.internal.win32.OS.CallWindowProc(Native Method)
	at org.eclipse.swt.widgets.Label.callWindowProc(Label.java:122)
	at org.eclipse.swt.widgets.Control.windowProc(Control.java:4881)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:5106)
	at org.eclipse.swt.internal.win32.OS.UpdateWindow(Native Method)
	at org.eclipse.swt.widgets.Decorations.setVisible(Decorations.java:1325)
	at org.eclipse.swt.widgets.Shell.setVisible(Shell.java:2133)
	at org.eclipse.swt.widgets.Shell.open(Shell.java:1297)
	at com.levitasoft.om.client.ide.ImageDisable.main(ImageDisable.java:63)

The problem does not occur if any of the following is true:

  1. The sourceImage has been loaded via new Image(display, "SourceImage.png")
  2. The sourceImage itself has been displayed before the disableImage (but then disableImage is NOT grayed out!)

To Reproduce

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import java.io.ByteArrayInputStream;
import java.nio.file.Files;
import java.nio.file.Path;

public class ImageDisable
{
  public static void main(String[] args) throws Exception
  {
    Display display = new Display();
    Image sourceImage;

    if (true)
    {
      byte[] bytes = Files.readAllBytes(Path.of("SourceImage.png"));
      sourceImage = new Image(display, new ByteArrayInputStream(bytes));
    }
    else if (true)
    {
      byte[] bytes = Files.readAllBytes(Path.of("SourceImage.png"));
      Files.write(Path.of("SavedImage.png"), bytes);
      sourceImage = new Image(display, "SavedImage.png");
    }
    else
    {
      sourceImage = new Image(display, "SourceImage.png");
    }

    Image disabledImage = new Image(display, sourceImage, SWT.IMAGE_DISABLE);

    Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());

    if (true)
    {
      new Label(shell, SWT.NONE).setImage(sourceImage);
      new Label(shell, SWT.NONE).setImage(disabledImage);
    }
    else
    {
      Canvas canvas = new Canvas(shell, SWT.NONE);
      canvas.addPaintListener(new PaintListener()
      {
        public void paintControl(PaintEvent e)
        {
          e.gc.drawImage(sourceImage, 10, 10);
          e.gc.drawImage(disabledImage, 10, 50);
        }
      });
    }

    shell.open();
    while (!shell.isDisposed())
    {
      if (!display.readAndDispatch())
      {
        display.sleep();
      }
    }

    display.dispose();
  }
}

Expected behavior
The disabledImage must be displayed grayed out and without SWTError, no matter how the sourceImage was created. Just like in before-2025-06.

Environment:

  1. Select the platform(s) on which the behavior is seen:
    • All OS
    • Windows
    • Linux
    • macOS
  1. Additional OS info (e.g. OS version, Linux Desktop, etc)
    Windows 11

  2. JRE/JDK version
    JDK-21

Version since
2025-06 (M something)
org.eclipse.swt_3.130.0.v20250514-1209.jar

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions