Skip to Content

GUI Applications: Overview

Building a GUI application—one with a Graphical User Interface, or GUI—is not too hard once you understand the basic architecture and control flow of how a GUI application works. Maybe you have programmed lots of course assignments already, but these all started at main() and then ended when your code finished. All the time, your code was in control.

The first fundamental mental shift that you have to make for GUI programming is that your code is not in control. Rather, the GUI framework is in control, and it invokes your code only when it knows it is necessary.

The basic high-level architecture for a GUI Application is shown below. This page describes the basics of how all GUI applications behave, but it does not describe any specifics for any single GUI framework. You’ll need to read those on your own!

GUI Application Operation

When you build your GUI program, you use some GUI Framework (or library), such as Java/Swing, JavaFX, FLTK, Windows Foundation, MacOS Appkit, QT, etc.

The GUI Framework displays the GUI window to the user, and recognizes the actions that the user does: pushing a button, selecting a tab, checking a checkbox widget, entering text in a text field, scrolling, etc. The GUI framework mostly knows how to update the user’s view for simple widgets—for example, it knows how to visually make the button press happen—but it does not know what that action should mean inside your application. So the GUI framework calls back into your code when that action happens.

We call those actions events, and the code that the GUI calls in your code is called an event handler.

Basic Parts of a GUI Application

Startup Code: In the figure this is shown as main(), but of course it should be better designed and not just left all in main(). The point of the diagram is that it all happens from main(), when your application is starting up. Your startup code must:

  1. Initialize your application domain code. This may involve creating objects, reading data files, or whatever, but your application needs to be initialized.

  2. Initialize and construct the GUI. Different GUI frameworks have different ways of doing this, but the GUI side also needs initialized. In some frameworks you will have function/method calls for every widget that is part of the GUI. Selecting and configuring window packing is usually the tricky part!

  3. As part of constructing the GUI, your code needs to connect the GUI widgets to their event handlers. More on this below.

  4. Hand off control to the GUI framework. This is where your code gives control to the GUI framework and is no longer in charge. Now your code just waits…

Application Domain Code: This is the code that handles the actual domain functionality of your program, the reason your program exists in the first place! It is really easy to intertwine your application domain code with your GUI interaction code, but this is a bad idea, and you should work hard to keep it separate.

GUI Event Handlers: These are typically methods or functions that the GUI framework invokes when an event happens in the GUI. When your program is constructing the GUI, it will tell the GUI what the event handlers are for each widget or each possible event from the window. In many Object Oriented frameworks, this is often an object in your application that implements a specific method or interface. For example, in Java/Swing if your GUI has a button in it, that button needs a reference to an object of a class that implements the ActionListener interface; when the button is pressed the Swing framework will invoke the actionPerformed() method on that object.

GUI Update Code: Some parts of the GUI window cannot be automatically updated by the GUI. Your program might need to draw some graphics, or place some new text in a text box, or change some labels or other information on the screen. After your application code is invoked from an event happening, it might need to make the GUI do some updates. As with other GUI code, it is easy to intertwine this into your application code, but you should really resist that temptation, and keep it separate. Depending on what the GUI updates are, your code might need to explicitly tell the GUI to redraw the window (or a specific widget or area); each framework has specific ways of doing this.

Design Considerations

The diagram above is really a vague architecture – a high level view – but it does not give you very much guidance for designing your program. So you still have lots of thinking to do in order to build a well-designed program. Below are a few thoughts.

The diagram above roughly corresponds to a Model-View-Controller architecture, or MVC, where the Model is the Application Code, the View is the GUI library itself and the GUI Update code, and the Controller is the Event Handlers and the GUI construction from main(). The MVC architecture tells us that it is good to keep these things separated and especially to keep application code (the Model part) separate from the GUI code (View and Controller).

In an Object-Oriented (OO) language, event handlers are typically objects (FLTK is mostly OO but has plain C event handler functions; I wish it didn’t!). You have to decide what sort of objects will handle the GUI events. Some design ideas might conglomerate related events and let them be handled by one object, while other design ideas have unique objects per event handler. In Java some programmers like to use anonymous objects to handle events, though I tend to avoid this practice (and I think most people don’t really understand what they are doing when they do this). Java anonymous objects are really a way of centralizing the Controller code because the anonymous objects have access to the enclosing context (and object) from which they are created.

The GUI Update code, which must access application (Model) data in order to tell the GUI what to display or how to update, can often feel very intertwined with the Model code. One OO way to separate it is to use inheritance to subclass your application classes that have data to be displayed, and then isolate the GUI update code in those subclasses.

Resources

The official Oracle Java Tutorials have introductions to Swing and JavaFX, and other useful tutorials such as 2D graphics and sound.

FLTK has extensive documentation for itself.

This Python GUI page lists lots of options in building GUI programs in Python. TKinter (PyTK) is listed as the “standard” GUI, but it seems that these days there are lots of choices.

Qt is a popular cross-platform GUI toolkit.

WxWidgets is also a popular cross-platform GUI.

GTK is a heavily used Unix/Linux GUI toolkit. Lots of the “standard” Linux applications are built on top of GTK.

A short tutorial for the basics of Game Development in JavaFX

A JavaFX Blog; one of its page on sprites and animation

A programmer’s blog with tags for JavaFX, UI development, and plenty of others.