This is a Gtk tutorial using Java.
Learning GUI programming with Java and Gtk.
- Basic knowledge of Java (Loop, Conditionals, OOP, etc.)
- Lambdas.
- Download this program and install it. (It's called MSYS2)
- Open MSYS2 and paste the following commands:
pacman -S mingw-w64-x86_64-gtk4
pacman -S mingw-w64-x86_64-libadwaita
-
Clone this repository.
var app = new Application("com.example.hello", ApplicationFlags.FLAGS_NONE);
app.onActivate(() -> {
Window window = new ApplicationWindow(app);
window.show();
});
app.run(args.length, new Strs(args));
var app = new Application("com.example.hello", ApplicationFlags.FLAGS_NONE);
app.onActivate(() -> {
Window window = new ApplicationWindow(app);
Button button = new Button();
button.setLabel("Click Me !");
window.setChild(button);
window.show();
});
app.run(args.length, new Strs(args));
Important
You have to treat the onActivate() handler as your main() method for the GUI. Given that, I'm going to omit Application creationg from the following code and you have to put it inside onActivate() handler.
Window window = new ApplicationWindow(app);
Label label = new Label("HelloWorld");
window.setChild(label);
window.show();
Window window = new ApplicationWindow(app);
Button button1 = new Button();
button1.setLabel("Click Me !");
Button button2 = new Button();
button2.setLabel("Click Me !");
Button button3 = new Button();
button3.setLabel("Click Me !");
Box box = new Box(Orientation.HORIZONTAL, 0);
box.append(button1);
box.append(button2);
box.append(button3);
window.setChild(box);
window.show();
Note
To organize them vertically, change Orientation.HORIZONTAL to Orientation.VERTICAL
Window window = new ApplicationWindow(app);
Button button1 = new Button();
button1.setLabel("Click Me !");
Button button2 = new Button();
button2.setLabel("Click Me !");
Button button3 = new Button();
button3.setLabel("Click Me !");
button2.setHexpand(true);
Box box = new Box(Orientation.HORIZONTAL, 0);
box.append(button1);
box.append(button2);
box.append(button3);
window.setChild(box);
window.show();
Window window = new ApplicationWindow(app);
Button button1 = new Button();
button1.setLabel("Click Me !");
Button button2 = new Button();
button2.setLabel("Click Me !");
Button button3 = new Button();
button3.setLabel("Click Me !");
Box box = new Box(Orientation.HORIZONTAL, 0);
box.setHalign(Align.END); // START, END, CENTER, FILL
box.append(button1);
box.append(button2);
box.append(button3);
window.setChild(box);
window.show();
Tip
Available alignments are START, END, CENTER and FILL. START, END and CENTER squeezes children to a small area, while FILL makes them fill all the area.
- Every item that appears on the screen is called a widget.
- Some widgets can contain other widgets, hence they are called containers.
- Widgets inside a container are called children of that container.
- Containers' job is to organize its children in a certain way.
- Some containers can only hold one child (like Window).
Visit Gtk Widget Gallery to discover some of the available widgets in Gtk.
Picture pic = new Picture();
pic.setFilename("src/main/resources/media/numbers_in_quran.jpg");
- LevelBar
LevelBar bar = new LevelBar();
bar.setMaxValue(100);
bar.setMinValue(0);
bar.setValue(30);
- TextView
- Entry
- PasswordEntry
- ToggleButton
- CheckButton
- Switch
- Spinner
Try to find the API of the above in Gtk4 Documentation
An event is something interseting happening, like a button click, mouse motion, keyboard input, etc.
Window window = new ApplicationWindow(app);
Button button = new Button();
button.setLabel("Click Me !");
button.onClicked(()->{
System.out.println("Button Clicked !");
});
window.setChild(button);
window.show();
Window window = new ApplicationWindow(app);
TextView view = new TextView();
view.getBuffer().onChanged(()->{
System.out.println("Text Changed");
});
window.setChild(view);
window.show();
So far the containers we have seen are Window and Box, but there are more, check Gtk Widget Gallery's containers section for more containers.
If you have a large widget you should put in here to add a scollbar.
Let's take the following example of adding 100 buttons to a box, and adding the box to a ScrolledWindow
Window window = new ApplicationWindow(app);
Button buttons[] = new Button[100];
for(int i=0 ; i<buttons.length ; i++){
buttons[i] = new Button();
buttons[i].setLabel("Button "+i);
}
Box box = new Box(Orientation.VERTICAL, 0);
for(int i=0 ; i<buttons.length ; i++){
box.append(buttons[i]);
}
ScrolledWindow scrolledWindow = new ScrolledWindow();
scrolledWindow.setChild(box);
scrolledWindow.setPolicy(PolicyType.NEVER, PolicyType.ALWAYS);
window.setChild(scrolledWindow);
window.show();
To create a custom titlebar, use HeaderBar. This way you can add buttons to the titlebar for example.
Window window = new ApplicationWindow(app);
Button saveButton = new Button();
saveButton.setLabel("Save");
HeaderBar titlebar = new HeaderBar();
titlebar.packStart(saveButton);
TextView view = new TextView();
window.setTitle("Notes");
window.setTitlebar(titlebar);
window.setChild(view);
window.show();
A stack is a container that only shows one of its children at a time.
Window window = new ApplicationWindow(app);
Button button1 = new Button();
button1.setLabel("Article 1");
Button button2 = new Button();
button2.setLabel("Article 2");
HeaderBar titlebar = new HeaderBar();
titlebar.packStart(button1);
titlebar.packStart(button2);
TextView view = new TextView();
String str = "Lorem ipsum dolor sit amet,\n consectetur adipiscing elit,\n sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n\n";
view.getBuffer().setText(str, str.length());
Image image = Image.newFromFileImage("src/main/resources/media/numbers_in_quran.jpg");
Stack stack = new Stack();
stack.addChild(view);
stack.addChild(image);
button1.onClicked(()->{
stack.setVisibleChild(view);
});
button2.onClicked(()->{
stack.setVisibleChild(image);
});
window.setTitle("Stack Demo");
window.setTitlebar(titlebar);
window.setChild(stack);
window.show();
A dialog is a temorary window that shows or asks user some information, then closes. Check Gtk4 Widget Gallery's Windows section for examples.
It's a window that shows information about the application (ex: program name, developer name, license, website, etc.)
AboutDialog aboutDialog = new AboutDialog();
aboutDialog.setProgramName("Gtk Tutorial");
aboutDialog.setAuthors(new Strs(new String[]{"Hamza Algohary"}));
aboutDialog.setVersion("0.6.0");
aboutDialog.show();
A dialog to ask the user to select a file or a folder to open or save.
Window window = new ApplicationWindow(app);
FileChooserDialog fileChooserDialog = new FileChooserDialog("Open File", window , FileChooserAction.OPEN , "Open" , 0 , "Cancel" , 1);
fileChooserDialog.onResponse((int response)->{
if(response == 0)
System.out.println("Opening " + fileChooserDialog.asFileChooser().getFile().getPath().toString());
else
System.out.println("Operation Cancelled");
fileChooserDialog.hide();
});
window.show();
fileChooserDialog.show();
Check the documentation to understand the constructor.
Glib.timeoutAdd(1000, (handler,user_data)->{
System.out.println("Hello.");
return GlibConstants.SOURCE_CONTINUE;
}, null);
public static int times = 0;
Glib.timeoutAdd(1000, (handler,user_data)->{
System.out.println("Hello.");
times++;
if(times > 10)
return GlibConstants.SOURCE_REMOVE;
return GlibConstants.SOURCE_CONTINUE;
}, null);
- Use setSizeRequest() on any widget to force a minimum size for it.
- Use setDefaultSize() to set window initial dimensions.
Gtk widgets can be styled using CSS. To load an external CSS file:
CssProvider provider = new CssProvider();
StyleContext.addProviderForDisplay(window.getDisplay(), provider.asStyleProvider(), 10000);
provider.loadFromPath("src/main/resources/themes/canta-light/gtk.css");
You can also change the margin around a widget programmatically using these methods:
- setMarginStart()
- setMarginEnd()
- setMarginTop()
- setMarginBottom()