Basics
Basics
To begin our introduction to GTK, we'll start with a very simple application. This program will create an empty 200 × 200 pixel window.
First, create a small Gradle project with the recommended layout:
[top-level project folder]
├── src/
│ ╰── main/
│ ├── java/
│ │ ╰── Example0.java
│ ╰── resources/
╰── build.gradle
Add the following content into the top-level gradle.build
file:
plugins {
id 'application'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'io.github.jwharm.javagi:gtk:0.11.0'
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(22)
}
}
tasks.named('run') {
jvmArgs += "--enable-native-access=ALL-UNNAMED"
}
application {
mainClass = "Example0"
}
Note
In this guide, we use Gradle to build the program and download dependencies. However, we don't use any Gradle-specific features or plugins. You can equally use Maven or any other build tool you prefer, or simply use your IDE project settings.
Enter the following content into Example0.java
.
import org.gnome.gtk.*;
import org.gnome.gio.ApplicationFlags;
public class Example0 {
public static void main(String[] args) {
Application app = new Application("org.gtk.example", ApplicationFlags.DEFAULT_FLAGS);
app.onActivate(() -> {
Window window = new ApplicationWindow(app);
window.setTitle("Window");
window.setDefaultSize(200, 200);
window.present();
});
app.run(args);
}
}
Save the java source file in the src/main/java
folder.
You can compile and run the program with Gradle using:
Tip
If the above command does not work, make sure all prerequisites are installed:
-
Gradle version 8.7 or higher (check with
gradle --version
) -
Java version 22 or higher (check with
java --version
) -
Gtk version 4 or higher (check with
pkg-config --modversion gtk4
) -
GLib version 2.74 or higher (check with
pkg-config --modversion glib-2.0
)
All GTK applications will, of course, import classes from org.gnome.gtk
. Top-level functions and constants are in the class org.gnome.gtk.Gtk
.
In a GTK application, the purpose of the main()
method is to create a Gtk.Application object and run it. In this example a Gtk.Application instance named app
is initialized using new Application()
.
When creating a Gtk.Application, you need to pick an application identifier (a name) and pass it to new Application()
as parameter. For this example org.gtk.example
is used. For choosing an identifier for your application, see this guide. Lastly, new Application()
takes ApplicationFlags
from package org.gnome.gio
as input for your application, if your application would have special needs. To pass a combination of multiple flags, use Set.of(flags1, flag2, ...)
.
Next the activate signal is connected to a callback method (or, in this case, lambda). The activate
signal will be emitted when your application is launched with Application.run()
on the line below.
The run()
call takes as arguments the command line arguments (the args
String array). Your application can override the command line handling, e.g. to open files passed on the commandline.
Within Application.run()
the activate signal is sent and we then proceed to handle that signal. This is where we construct our GTK window, so that a window is shown when the application is launched. The call to new ApplicationWindow()
will create a new Gtk.ApplicationWindow and store it inside the window
variable. The window will have a frame, a title bar, and window controls depending on the platform.
A window title is set using Window.setTitle. This method takes a String as input. Finally the window size is set using Window.setDefaultSize and the window is then shown by GTK via Window.present.
When you close the window, by (for example) pressing the X button, the Application.run()
call returns and the application exits. In a C app, a call to g_object_unref
would be required here to free the Application
object. In Java, a Cleaner will do this after the garbage collector has freed the Application
object.
While the program is running, GTK is receiving events. These are typically input events caused by the user interacting with your program, but also things like messages from the window manager or other applications. GTK processes these and as a result, signals may be emitted on your widgets. Connecting handlers for these signals is how you normally make your program do something in response to user input.
The following example is slightly more complex, and tries to showcase some of the capabilities of GTK.