To create a Java GUI with native look and feel at native performance, SWT(Standard Widget Toolkit) is a good choice. With Skija, it got even more powerful. And finally it’s able to create a real native application with the help of the GraalVM native image.
SWT and Skija
For some applications, standard widgets is enough. Though if you want draw some fancy graphics, the 2D graphics in SWT is not powerful enough. Java 2D is quite powerful, but it can’t be used on SWT directly. You have to use off screen buffer then copy data around, it’s often slow and use more memory. Using Skia in SWT is much easier with Skija, which is the Java binding for Skia.
To use Skija in SWT, simply create a GLCanvas.
GLData data = new GLData();
data.doubleBuffer = true;
GLCanvas glCanvas = new GLCanvas(shell, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE, data);
glCanvas.setCurrent();
DirectContext context = DirectContext.makeGL();After that you can you can create Surface and canvas
Rectangle rect = glCanvas.getClientArea();
BackendRenderTarget renderTarget = BackendRenderTarget.makeGL(rect.width, rect.height, /*samples*/0, /*stencil*/8, 0, FramebufferFormat.GR_GL_RGBA8);
Surface surface = Surface.makeFromBackendRenderTarget(context, renderTarget, SurfaceOrigin.BOTTOM_LEFT, SurfaceColorFormat.RGBA_8888, ColorSpace.getDisplayP3());
Canvas canvas = surface.getCanvas();
canvas.clear(0xFFFFFFFF);
context.flush();
glCanvas.swapBuffers();Screenshots
With Skia and GraalVM, you can do lots of things, for example:
- A Flash render using Skia, and a ActionScript VM on top of GraalVM.
- Port SWT itself to OpenGL, make it possible to write GUI for mobile, or run Eclipse without X11.
This example only demonstrate how to render SVG and play Lottie animation.
| SVG on Windows 7 32 |
|---|
![]() |
| Lottie on Raspberry Pi OS 64 |
|---|
![]() |
Native Image
Build a native iamge is very simple, for example, this is how you run java application:
And to build the native image:
native-image -jar aaa.jarThings will get bit complicate if you use reflection in java or jni. luckily, you can use GraalVM tracing agent to simplify the configuration.
Source code and binary
Source and binary for Raspberry Pi OS 64. To build source, you need:
- SWT 4.18 for AArch64, SWT 4.9 is the latest for Win32.
- GraalVM Community Edition, 20.3 or 21.0 would be fine.
- Skija for aarch64 or Win32, other platform
./build.sh
./run -trace
./build -nativeTo run the demo, you need install these packages:
sudo apt install libharfbuzz-icu0 libpng16-16 libjpeg62-turbo libexpat1 libwebpmux3 libwebpdemux2 libicu63And the memory footprint of Java vs Native:
| Java |
|---|
![]() |
| Native |
|---|
![]() |
Conclusion
GraalVM native image still has long way to go, but SWT, Skija and GraalVM is great combination for build native GUI application.



