1. Gluon Particle Overview

Gluon Particle is a 'convention over configuration' application framework designed exclusively for building cross-platform desktop applications. It has been designed from the ground up with a focus on having a minimal API, and to also handle as much of the work behind the scenes as possible.

Gluon Particle enforces very little constraints on developers, but there are important things to understand, so that you make best use of the conventions expected by Gluon Particle. The purpose of this documentation is to explain how to best utilize Gluon Particle. If you have any questions or feedback, please reach out to the Gluon Forums.

For the same reason we value simplicity and small APIs, we will strive to keep this document succinct and to the point. However, if you feel an important detail is missing, please let us know.

1.1. Gluon Particle Features

1.1.1. Runtime Annotation Scanning

Gluon Particle ships with a small number of annotations that can be used by developers to annotate relevant aspects of their software. Gluon Particle can scan for these annotations at runtime to discover and make available these classes in the approriate way. These annotations are detailed later, in the Gluon Particle Annotations section.

1.1.2. Support for Dependency Injection

Gluon Particle does not internally use any dependency injection framework, but if a developer wishes to benefit from dependency injection, it is highly recommended that Gluon Particle be used in conjunction with the open source Gluon Ignite library. This library abstracts away the specifics of any one DI framework, and adds support for dependency injection into FXML controllers.

1.1.3. Gluon Particle Dependency Injection

For developers who decide to not use a dependency injection framework, Gluon Particle still offers many of the benefits of injection (without the need of bringing in any additional external libraries). The way it works is, when loading certain classes (e.g. views and controllers), Gluon Particle will scan the class for fields with the standard Java @Inject annotation. If any such fields exist, Gluon Particle will attempt to populate these fields with the appropriate values. Refer to the Gluon Particle Dependency Injection section below to understand what injections are supported.

1.1.4. Resource Injection

Gluon Particle can take care of automatically discovering and loading resources. There are currently two types of resources that Gluon Particle can work with:

  1. Translation (Resource) Bundles:: Gluon Particle supports translation (resource) bundles on a per-view basis. This means that for every view, Gluon Particle will attempt to find a similarly named resource bundle in a pre-specified location. If this file is discovered, it is loaded and can be injected into the view (regardless of whether the view is defined in code or in FXML - in which case it is also injected into the FXML controller as well).

  2. Application configuration: Gluon Particle will scan for the presence of a *.properties file at startup, and if discovered this will be loaded and made available to your application to query programatically. In addition to this, certain properties can be set in this properties file that will impact the operation of Gluon Particle.

For more detail on resource injection, refer to the resource injection section later in this document.

2. Gluon Particle Annotations

Gluon Particle currently ships with four annotations:

  • License - The @License annotation is used to signify that the application is licensed, and as such receives the benefits of the non-free edition of Gluon Particle. This annotation can be on any class in your application, but it is common practice to place this on your main application class (which typically extends from ParticleApplication).

  • ParticleActions - The @ParticleActions annotation signifies a class that contains one or more of the ControlsFX @ActionProxy annotations. By annotating the containing class, all @ActionProxy annotations will be discovered and loaded into Particle ready for addition to the Particle Menubar and / or ToolBar controls.

  • ParticleForm - Annotation for classes that extend from the Form interface. By annotating classes with @ParticleForm, you are allowing for Particle to discover these forms at runtime and to prepare them ready for display at the appropriate times through using the `FormManager.

  • ParticleView - Annotation for classes that implement the View interface. By annotating these classes with @ParticleView, you are allowing for Particle to discover these views at runtime and to prepare them ready for display at the appropriate times through using the ViewManager.

As should hopefully be evident, by using these annotations in appropriate places, you can remove the burden of manually wiring up various aspects of your application (although this is still possible).

3. Dependency Injection

As noted, Gluon Particle will scan most classes that are instantiated directly by Gluon Particle (e.g. views, forms, actions, etc) for fields annotationed with the standard Java @Inject annotation. If any such fields exist, Gluon Particle will attempt to populate these fields with the appropriate values.

The tables below details which injections are available.

3.1. Singleton Injections

Within Gluon Particle are a few singletons, and these can be injected and used as desired. These include:

Injection Type Details

Particle

The single instance of Particle that exists in the application.

ParticleApplication

The single instance of ParticleApplication, if it exists (which is only the case when developers create their application by extending ParticleApplication, rather than the JavaFX Application class.

ViewManager

The single instance of ViewManager that exists in the application.

FormManager

The single instance of FormManager that exists in the application.

StateManager

The single instance of StateManager that exists in the application.

MenuBar

The single instance of the MenuBar control that exists in the application.

ToolBar

The single instance of the ToolBar control that exists in the application.

StatusBar

The single instance of the StatusBar control that exists in the application.

FXMLLoader

A shared, single instance of a JavaFX FXMLLoader.

3.2. Specialized Injections

There are at present two specialised injections that are available:

Injection Type Details

String

If the field is a String, and named particleName, then the name of the Particle application will be injected into this field. The Particle name is what is passed in to the ParticleApplication or Particle constructors.

ResourceBundle

If the field type is ResourceBundle, and the field is contained in a class that implements View or extends Form, then this field will be injected by a resource bundle located in the bundles directory (which is beneath the root directory of the application, with the bundle name being the name of the View / Form. If no bundle exists in this location, it will be set as null.

4. Resource Injection

As noted earlier, Gluon Particle supports two notions of resource injection, and these are covered in more detail in this section.

4.1. Translation (Resource) Bundles

Gluon Particle supports translation (resource) bundles on a per-view or per-form basis. This means that for every view or form, Gluon Particle will attempt to find a similarly named resource bundle in a pre-specified location. If this file is discovered, it is loaded and can be injected into the view (regardless of whether the view is defined in code or in FXML - in which case it is also injected into the FXML controller as well). For Gluon Particle to handle this automatically, it requires the following conditions be met:

  1. That the view or form be named (using the @ParticleView and @ParticleForm annotations mentioned in the dependency injection section earlier).

  2. Within the resources directory, there exists a file with the name of the view or form and .properties extension, that is either added to the same package as the view or form, or to a bundles folder within the root of the application directory.

  3. Within the view or form, there is a field declared in the following way: @inject private ResourceBundle resourceBundle. In the case of the FXML controller, the resource bundle can be passed via the two arguments initialize method, or adding the field @FXML private ResourceBundle resources when using the no-argument method.

By meeting these three criteria, the resource bundle will be automatically discovered and made available for use within your views and forms.

4.1.1. Styling

Every View includes the styleclass view, so CSS styling can be easily applied to them.

CSS stylesheets will be automatically added to the View, if the css file with the same name is present in the same package.

As well, Form has the styleclass form applied, and CSS stylesheets will be added to it, in case a css file with the same name is present in the same package.

4.2. Application configuration

Gluon Particle has two separate notions of application configuration. Firstly, there is the immutable configuration properties that can be set by developers or end users, but which are not changed by Gluon Particle (that is, they are considered read-only properties). Secondly, there is the StateManager, which based on the specific implementation used, will read and write properties as appropriate.

4.2.1. Application Configuration

Gluon Particle scans for the presence of application properties in two locations:

  1. Firstly, if a particleName is specified in the Particle or ParticleApplication constructors, it will look for a file within the config directory (which is a directory within the root of the application directory) with the particleName, and .properties as the file extension.

  2. If there is no particleName specified, or no file found, Gluon Particle will then attempt to load a file named application.properties from within the same config directory.

These properties can not be read by developers at runtime, they are simply used to configure Gluon Particle itself. For this reason, the following table will detail what properties are available to be set, and what functionality they provide:

Property Key Details

particle.showCloseConfirmation

Can either be true or false. This specifies whether a confirmation dialog is shown to users to confirm that they want to exit the application. If they click 'no', the application will not shut down.

particle.viewManager.scanPath

A comma-separated string of package names. This specifies what packages to scan for views.

particle.formManager.scanPath

A comma-separated string of package names. This specifies what packages to scan for forms.

particle.stateManager.persistenceMode

Can be either USER or GLOBAL. This specifies whether state persistence is stored for each user separately (based on the currently logged in user on the computer), or whether it should be stored in a global way, so all users get the same state between executions of the application.

particle.stateManager.stateIO.impl

A fully-qualified class name for a class that implements the StateIO interface. If none is specified, a default implementation is used.

4.2.2. State Management

As opposed to the read-only application configuration detailed above, the Gluon Particle state manager allows for read and write operations. This is the API that should be used if you want to persist configuration details between runs. To get the state manager, you can either call the getStateManager() API on the Particle class, or else you can (in many places) simply annotate a field and Gluon Particle will inject it for you (e.g. @Inject private StateManager stateManager;).

Once you have the StateManager singleton, you can get and set properties using the available API. The state manager will ensure that theses properties are written out when the application closes, and will read them in again when the application is next started.

5. Views

All Gluon Particle views have two basic requirements:

  1. They must implement the View interface (either directly, or by extending the FXMLView class)

  2. They must be annotated with @ParticleView.

The View interface defines a life cycle API (which is optional, all methods are 'default' methods with no-op implementations), as well as the getContent() method that must be implemented and must return the root node of the view.

For developers who prefer to use FXMLView, there exists the FXMLView class that implements the View interface, but which handles the loading of an FXML file, as well as the injection of Gluon Particle objects into the FXML Controller, if one is specified.

5.1. Switching Views

To switch between views a developer simply needs to make use of API on the ViewManager. To get the view manager, you can either call the getViewManager() API on the Particle class, or else you can (in many places) simply annotate a field and Gluon Particle will inject it for you (e.g. @Inject private ViewManager viewManager;). Once the ViewManager has been retrieved, switching views is simply a matter of using the available switchView methods (by either passing in a view name, or a view class).

6. Forms

All Gluon Particle forms have two basic requirements:

  1. They must extend the Form class,

  2. They must be annotated with @ParticleForm.

The Form class is abstract, and includes a number of methods that must be implemented (as well as a life cycle API which has default, no-op implementations). The abstract methods that need to be implemented are the following:

Method Details

String getTitle()

Returns the title to show in the form popup dialog window.

String getMessage()

Returns the message to show in the content area of the form popup dialog window, above the form.

Node getView()

Returns the form itself, which will be displayed in the form popup dialog window beneath the message.

void importModel(T model)

This method expects that the given model object will be loaded into the view (e.g. TextFields will be populated with the values taken out of the model, etc).

exportModel(T model)

This method should take the data out of the view controls and set the appropriate fields on the given model object.

6.1. Showing A Form

To show a form a developer simply needs to make use of API on the FormManager. To get the form manager, you can either call the getFormManager() API on the Particle class, or else you can (in many places) simply annotate a field and Gluon Particle will inject it for you (e.g. @Inject private FormManager formManager). Once the FormManager has been retrieved, showing a form can be achieved by using code such as the following:

formManager.getForm(PersonForm.class, Form.UpdateMode.UPDATE_NEW_INSTANCE)
           .ifPresent(form -> form.configure(new Person("Mark", "Twain", 180))
                                  .resizable(false)
                                  .showAndWait());