Fork me on GitHub

Application Layer

How to create your first start class.

Starting Point

First Class to extend

JRebirth Application Framework offers a custom class that extends the basic javafx.Application class, the aim is to automatically start the JRebirth underlying Application Framework without doing complex stuff.

Short UML Diagram:

Application Class Diagram

So you just have to extend org.jrebirth.core.application.AbstractApplication to be able to use JRebirth features.

If you have used the Maven archetype org.jrebirth.archetype you obtained this source code otherwise you could copy-paste it:

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public final class SampleApplication extends AbstractApplication<StackPane> {
 
    /**
     * Application launcher.
     *
     * @param args the command line arguments
     */
    public static void main(final String... args) {
        Application.launch(SampleApplication.class, args);
    }
 
    /**
     * {@inheritDoc}
     */
    @Override
    public Class<? extends Model> getFirstModelClass() {
        return SampleModel.class;
    }
 
    /**
     * {@inheritDoc}
     */
    @Override
    protected void customizeStage(final Stage stage) {
        stage.setFullScreen(false);
    }
 
    /**
     * {@inheritDoc}
     */
    @Override
    protected void customizeScene(final Scene scene) {
        addCSS(scene, SampleStyles.MAIN);
    }
 
    /**
     * {@inheritDoc}
     */
    @Override
    public List<FontItem> getFontToPreload() {
        return Arrays.asList(new FontItem[] {
                SampleFonts.SPLASH,
        });
    }
 
    /**
     * {@inheritDoc}
     */
    @Override
    public List<Wave> getPreBootWaveList() {
        return Collections.emptyList();
    }
 
    /**
     * {@inheritDoc}
     */
    @Override
    public List<Wave> getPostBootWaveList() {
        return Collections.emptyList();
    }
 
}

This class skeleton provides some hooks to allow customization of the application start up.
The AbstractApplication is using a generic type that represents the first JavaFX node hold by the scene. This node will be instantiated automatically by the framework and could be accessed by calling the protected method getRootNode(). You must define it in the class definition as generic type, this type must extend Pane class.

First Model Class

The method Class<? extends Model> getFirstModelClass() is mandatory to define which UI model will be attached to the root node of the scene.

This first model will be created into the JRebirth Thread Pool, then it will be attached to the root node into the JavaFX Application Thread.

Application Title

The method String getApplicationTitle() is simply used to define the name of the application displayed by the stage (OS window) and used by OS task bar.

Stage customization

The first stage object is provided by the JavaFX launcher, the method void customizeStage(final Stage stage) allows doing some stage customizations.

Scene customization

The scene object automatically attached to the default stage stage is built by the protected method Scene buildScene() that could be overridden as needed. By defaut it creates a default scene with these attributes :

  • Width = 800
  • Height = 600
  • Background Color = Transparent
  • Root = Automatically built according to the generic type used

Theses properties are customizable with a properties file, this is explained below into the Configuration section.

Another method let you customize the scene : void customizeSscene(final Scene scene) . For example you can listen some key binding to perform a global action. The Presentation application uses it to listen <Ctrl> + <+> and <Ctrl> + <-> key combo to zoom in/out the whole scene.

This method is also useful to attach a stylesheet to the scene like this : scene.getStylesheets().add(loadCSS("style/sample.css"));

Fonts preloading

JavaFX applications are able to use fonts throught programmatic declarations or with CSS declaration (in .css files. or inline).
If font used by CSS are not provided by the platform running the application, it must be provided and loaded by the application.
JRebirth provides a simple way to embed and declare font: this mechanism is explained in the custom topic: Managing Fonts.

The method List<FontEnum> getFontToPreload() is used to preload fonts to allow them to be used by CSS declaration. They are loaded at boot in the same time than stylesheets.

Running Waves

The JRebirth Application class allow running Waves before and after the creation of the first model class.

A Wave is a JRebirth Event that could be process by any JRebirth components, they are carrying throught JRebirth classes and threads.

You can add your own wave with the two following methods :

  • List<Wave> getPreBootWaveList()
  • List<Wave> getPostBootWaveList()

The waves returnes will be processed sequentially althought they could be processed by different threads.

In this method you are allowed to call visible methods from the javafx.application.Application class, in example the getParameter() will give you the arguments passed to command line

Don't forget that you can chain your waves if you need to do more than one thing.

JRebirth Analyzer example :

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
@Override
public List<Wave> getPostBootWaveList() {
 
    final List<Wave> waveList = new ArrayList<>();
    final Parameters p = getParameters();
    if (p.getRaw().size() >= 1) {
        final String etdFile = p.getRaw().get(0);
        final File file = new File(etdFile);
        if (file.exists()) {
 
            waveList.add(
                    WaveBuilder.create()
                            .waveGroup(WaveGroup.RETURN_DATA)
                            .waveType(LoadEdtFileService.DO_LOAD_EVENTS)
                            .relatedClass(LoadEdtFileService.class)
                            .data(WaveData.build(EditorWaves.EVENTS_FILE, file))
                            .build()
                    );
 
            waveList.add(
                    WaveBuilder.create()
                            .waveType(EditorWaves.DO_PLAY)
                            .build()
                    );
        }
    }
    return waveList;
}

Default key shortcuts

The AbstractApplication class is using two defaults hotkey:

  • 445
    protected KeyCode getFullScreenKeyCode() {
    KeyCode getFullScreenKeyCode() => to go to to fullscreen mode (default is < F10 >)
  • 456
    protected KeyCode getIconifiedKeyCode() {
    KeyCode getIconifiedKeyCode() => to go to iconified mode (default is < F11 >)

These methods could be overridden if you want to change them, you can avoid these shortcut by returning null .

Exception Manager

JRebirth creates its own uncaught exception handlers in order to log exceptions that were not caught by application code.
It's possible to customize them by overriding methods listed hereafter:

  • Exception handler of the JavaFX Application Thread
  • 474
    protected UncaughtExceptionHandler getJatUncaughtExceptionHandler() {
  • Exception handler of the JRebirth Internal Thread
  • 483
    protected UncaughtExceptionHandler getJitUncaughtExceptionHandler() {
  • Default Exception handler of all other threads
  • 465
    protected UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {

Manage Configuration

JRebirth provides a configuration engine that allow to parse configuration files and inject values into application.

@Configuration

Your application class can use the dedicated @Configuration annotation. The AbstractApplication class use a default one:

63
@Configuration(".*jrebirth")

Hereafter you have a full annotation usage:

18
@Configuration(value=".*-jrebirth", extension="properties", schedule=60)

This annotation has 3 properties:

  • value
  • extension
  • schedule

Value (default property)

Define the wildcard used to find configuration files.
The format is the same as Regex Pattern (ie: .*-jrebirth => for abc-jrebirth.EXTENSION files, abc matches the .* regex part)
The default value is empty, no search will be done

Extension

Define the file extension to find configuration files.
The extension must not included the first dot (ie: properties => for abc-jrebirth.properties files)
The default value is "properties" to load properties files

Schedule

Define the delay used to check if the file has changed in order to reload configuration files.
This value is in seconds.
The default value is 0, no check will be done (this feature is still under development)

Avoid Configuration

It's possible to avoid configuration mechanism, for example if you want to use your own and don't need another process at start-up.
You can disable it by setting an empty @Configuration annotation.

18
@Configuration