Launching the GUI

The graphical user interface (GUI) of the Friedolyn app is built with JavaFX, a somewhat modern and powerful (but sometimes also cumbersome) GUI framework for Java applications.

Windows vs Dialogs

When referring to graphical user interfaces (GUIs), we generally distinguish between windows and dialogs.

Windows are primary frames that provide main functionality and are meaningful on their own. They can be opened independently, and they open other windows or dialogs as needed.

Dialogs, on the other hand, are secondary frames that are used to perform specific tasks or to display information, for example asking the user for certain information or displaying error messages. All dialogs feature some kind of OK and Cancel button to let the user close them, and they may open other dialogs (but not windows). Dialogs always return the user’s input as a result of their execution, so it is advised to open them in a blocking manner (rather than non-blocking).

Caution

However, the actual GUI code does not reflect this semantic distinction, because windows and dialogs have been implemented in the exact same JavaFX way. The distinction is made here to provide a better understanding of the GUI’s structure and functionality.

Before you start

Due to the way JavaFX works, it is absolutely necessary to call the launch method of the Application class before opening any windows or dialogs. In other words, your class must extend Application and override its start method like this:

import javafx.application.Application;

public class MyAbsolutelyProfessionalGUI extends Application {
	@Override
	public void start(Stage primaryStage) {
		// your GUI code here, e.g.:
		GUI.openFirstLaunchWindow(false);
	}

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

Windows and dialogs available in the GUI

Currently, there are five windows/dialogs available in the graphical user interface (GUI):

First Launch window

This window is displayed when the app is launched for the first time. It asks the user to enter their Friedolin credentials and agree to the terms of service. When the user clicks the “Login” button, the credentials are checked with the Friedolin server and the setup dialog is opened.

Setup dialog

The setup dialog allows the user to configure the app’s settings, i.e. create a new Configuration in a graphical way. These are all the preferences currently available in the setup dialog:

  • the academic degree whose grades should be monitored
  • how often the app should check for new grades
  • the app’s data directory in the user’s file system
  • whether the grades should be downloaded as PDF files and whether old ones should be overwritten
  • how the user should be notified about new grades (via e-mail or push notification)
  • whether the actual grades should be revealed in the notification (always, only good ones, never) and which grades count as “good”
  • the user-agent string that Friedolyn should include in its HTTP requests

When launching the setup dialog, you need instantiate a Friedolyn object first and pass it to the dialog, so that it can pre-fill the GUI and update the user’s existing configuration.

Main window

The main window allows the user to start periodic grade fetching and open the setup dialog to change the app’s settings.

Contact dialog

The contact dialog allows the user to send help inquiries, feedback, bug reports or feature requests to the developers. It uses the user’s e-mail credentials specified in the Configuration to send the message as an e-mail. It is encrypted using the developer’s OpenPGP public key, so that only the developers can read the message.

When sending a help inquiry or a bug report, the user can choose to attach the app’s log file to the e-mail as well as certain system information (like the operating system, Java version, etc.), so that the developers can better understand the problem.

There’s also a star rating system to let the user indicate how satisfied they are with the app.

Configuration configuration = new Configuration("es13nsa", "correct horse battery staple");
Friedolyn.ContactRequest requestType = Friedolyn.ContactRequest.FEEDBACK;

GUI.DialogResult<String> result = 
	GUI.openContactDialog(configuration, requestType);

if (result.success() == FuzzyBoolean.TRUE && 
    result.result().isPresent()) {
	String email = result.result().get();
}

Miscellaneous dialogs

There are three more dialogs available in the GUI, but we will not discuss them here, because they’re closely tied to the dialogs mentioned above and are not meant to be opened independently:

  • Ntfy and UnifiedPush dialogs:
    These dialogs are opened by the Setup dialog when the user wants to configure the app’s notification preferences.
  • Contact method dialog:
    This dialog is opened by the Contact dialog immediately before submitting the user’s e-mail, asking them how the developers should reply to their message (via encrypted e-mail or some messenger).