Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/org.eclipse.swt.snippets/Snippets.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ To contribute a new snippet, [create a snippet contribution as a pull request](h
- [draw a disabled/grayed image at various zoom levels](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet382.png "Preview for Snippet 382")
- [compare algorithms for rendering disabled images](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet384.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet384.png "Preview for Snippet 384")
- [draw an image with watermark using ImageGcProvider](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet385.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet385.png "Preview for Snippet 385")
- [options for programmatically creating an image](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet387.java) – [(preview)](https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/previews/Snippet387.png "Preview for Snippet 387")

### **ImageData**
- [display an animated GIF](https://github.com/eclipse-platform/eclipse.platform.swt/tree/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet141.java)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*******************************************************************************
* Copyright (c) 2025 Vector Informatik GmbH and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.swt.snippets;

import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

/**
* Demonstrates different ways of programmatically creating an image with a GC
* <p>
* When creating an image programmatically, it is important to use an
* appropriate way of doing that when at the time of image creation it is not
* yet known at which zoom the image will be used. This is particularly the case
* when using monitor-specific scaling on Windows.
* <p>
* There are two general options how to programmatically create an image:
* <ul>
* <li>{@link ImageGcDrawer}: create an image with an {@link ImageGcDrawer};
* preferred way as the drawer will be called with the requested zoom when
* needed
* <li>{@link GC} on image: create an image with fixed dimensions and create a
* {@link GC} for the image to drawn on; this is the legacy way of drawing an
* image and should only be used if the whole drawing logic cannot be wrapped
* into an {@link ImageGcDrawer} but the {@link GC} may be passed around to
* collect drawing contributions from different places
* </ul>
* When using the second approach creating a {@link GC} on top of an image, it
* is important to not dispose the GC before using the image, as in that case
* the Windows implementation of an image can request its regeneration at the
* desired zoom from the GC. If the GC is disposed before the image is used at
* desired zoom, it may need to blurry-scale any existing drawing result to the
* requested zoom instead of sharply rendering it at that zoom.
* <p>
* This snippet demonstrates both proper usages of the above mentioned options
* as well as a usage that disposes the GC before consuming the image at the
* desired zoom, leading to a blurry result. To see such a bad result, the
* snippet needs to be executed on Windows and has to be moved between monitors
* with different monitor zooms.
* <p>
* For a list of all SWT example snippets see
* http://www.eclipse.org/swt/snippets/
* </p>
*/
public class Snippet387 {

private static final int PADDING = 5;
private static final int IMAGE_WIDTH = 270;
private static final int IMAGE_HEIGHT = 50;

public static void main(String[] args) {
activateMonitorSpecificScaling();

Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Programmatic Images");
shell.setSize(IMAGE_WIDTH + 2 * PADDING + 20, 3 * IMAGE_HEIGHT + 4 * PADDING + 40);

Image staticImage = createStaticImage(display, "Static Image with disposed GC", true);
Image staticImageUndisposedGC = createStaticImage(display, "Static Image with non-disposed GC", false);
Image dynamicImage = createDynamicImage(display, "Dynamic Image");

shell.addPaintListener(event -> {
GC gc = event.gc;
gc.drawImage(staticImage, PADDING, PADDING);
gc.drawImage(staticImageUndisposedGC, PADDING, 2 * PADDING + IMAGE_HEIGHT);
gc.drawImage(dynamicImage, PADDING, 3 * PADDING + 2 * IMAGE_HEIGHT);
});

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

private static void activateMonitorSpecificScaling() {
System.setProperty("swt.autoScale.updateOnRuntime", "true");
}

private static Image createStaticImage(Display display, String text, boolean disposeGC) {
Image staticImage = new Image(display, IMAGE_WIDTH, IMAGE_HEIGHT);
GC imageGC = new GC(staticImage);
try {
drawImageContent(imageGC, text, IMAGE_WIDTH, IMAGE_HEIGHT);
} finally {
if (disposeGC) {
imageGC.dispose();
}
}
return staticImage;
}

private static Image createDynamicImage(Display display, String text) {
return new Image(display, (gc, w, h) -> drawImageContent(gc, text, w, h), IMAGE_WIDTH, IMAGE_HEIGHT);
}

private static void drawImageContent(GC gc, String text, int width, int height) {
gc.drawRectangle(0, 0, width - 1, height - 1);
gc.drawText(text, PADDING, PADDING);
}

}
Loading