How to create your first start class.
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:
To trigger the start-up of your JavaFX application you must add a static void main method in order to call one of the static protected method provided :
94 104 115 124 134 | protected static void preloadAndLaunch( final String... args) { protected static void preloadAndLaunch( final Class<? extends Preloader> preloaderClass, final String... args) { protected static void preloadAndLaunch( final Class<? extends Application> appClass, final Class<? extends Preloader> preloaderClass, final String... args) { protected static void launchNow( final String... args) { protected static void launchNow( final Class<? extends Application> appClass, final String... args) { |
In example, SampleApplication will be launched with default JRebirth preloader (Application and Preloader classes are omitted) like below:
29 30 31 | public static void main( final String... args) { preloadAndLaunch(args); } |
If you want to use the JRebirthPreloader, you must include the JRebirth preloader artifact to your pom.xml file
1 2 3 4 5 | < dependency > < groupId >org.jrebirth.af</ groupId > < artifactId >preloader</ artifactId > < version >7.7.0</ version > </ dependency > |
You can create your own Preloader class, JRebirth send only ProgressNotification with two kind of values:
Hereafter you have the default JRebirthPreloader implementation.
To define your own Application class you have 2 options:
The AbstractApplication class will do all extra stuff required to launch JRebirth engine.
You don't have to bother about it.
This class skeleton provides some hooks to allow customization of the
application start up.
Please note that one method is mandatory ! You must define a first Model Class to load the first Model that will initialize the first Node attached to the RootNode (automagically created) )of your Scene.
If you have used the Maven archetype org.jrebirth.archetype you obtained this source code otherwise that you can copy-paste:
22 23 24 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 | public final class SampleApplication extends DefaultApplication<StackPane> { /** * Application launcher. * * @param args the command line arguments */ public static void main( final String... args) { preloadAndLaunch(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, }); } } |
AbstractApplication & DefaultApplication classes are 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.
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 (JTP), then it will be attached to the root node into the JavaFX Application Thread (JAT).
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.
By default it will retrieve values from properties file (default is jrebirth.properties):
The first stage object is provided by the JavaFX launcher, the method void customizeStage(final Stage stage) allows doing some stage customizations.
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 :
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"));
JavaFX applications are able to use fonts through 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.
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 :
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 :
97 98 99 100 101 102 103 104 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 | @Override public List<Wave> getPostBootWaveList() { final List<Wave> waveList = new ArrayList<>(); // Get Java command line parameters final Parameters p = getParameters(); if (p.getRaw().size() >= 1 ) { // The first parameter must contains the log file to parse final String logFileName = p.getRaw().get( 0 ); final File logFile = new File(logFileName); if (logFile.exists()) { // Call the service that will load and parse the log file waveList.add( WaveBuilder.create() .waveGroup(WaveGroup.RETURN_DATA) .waveType(LoadEdtFileService.DO_LOAD_EVENTS) .relatedClass(LoadEdtFileService. class ) .data(WaveData.build(EditorWaves.EVENTS_FILE, logFile)) .build() ); // Start the animation to show all components creation waveList.add( WaveBuilder.create() .waveType(EditorWaves.DO_PLAY) .build() ); } } return waveList; } |
The AbstractApplication class is using two defaults hotkey:
552 | protected KeyCode getFullScreenKeyCode() { |
563 | protected KeyCode getIconifiedKeyCode() { |
These methods could be overridden if you want to change them, you can avoid these shortcut by returning null .
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:
581 | protected UncaughtExceptionHandler getJatUncaughtExceptionHandler() { |
590 | protected UncaughtExceptionHandler getJitUncaughtExceptionHandler() { |
572 | protected UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { |
JavaFX applications haves 2 main phases while starting up:
The Initialization phase is composed by:
Customizable steps are handled by 2 methods to override:
190 191 192 193 | /** * Perform custom task before application initialization phase. */ protected abstract void preInit(); |
You can use notifyPreloader(new ProgressNotification(PROGRESS)) method where PROGRESS value
is between 0.11 and 0.29 in order to update finely the progression.
You can also display custom message (understandable by your preloader) by calling
notifyPreloader(new ProgressNotification(MESSAGE_ID)) where MESSAGE_ID is 200 or 300.
195 196 197 198 | /** * Perform custom task after application initialization phase and before starting phase. */ protected abstract void postInit(); |
You can use notifyPreloader(new ProgressNotification(PROGRESS)) method where PROGRESS value
is between 0.71 and 0.89 in order to update finely the progression.
You can also display custom message (understandable by your preloader) by calling
notifyPreloader(new ProgressNotification(MESSAGE_ID)) where MESSAGE_ID is 800 or 900.
JRebirth provides a configuration engine that allow to parse configuration files and inject values into application.
Your application class can use the dedicated @Configuration annotation. The AbstractApplication class use a default one:
67 | @Configuration ( ".*jrebirth" ) |
Hereafter you have a full annotation usage:
15 | @Configuration (value = ".*-jrebirth" , extension = "properties" , schedule = 60 ) |
This annotation has 3 properties:
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
JRebirth provides a Internationalization engine that allow to localize internal resources and also your resources. It parses properties files and inject values into application.
Your application class can use the dedicated @Localized annotation. The AbstractApplication class use a default one:
68 | @Localized ( ".*_rb" ) |
This annotation has 2 properties: