Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
569 lines (415 sloc) 22.2 KB

01 Setup the project

Intention

In 2008 I wrote a little game Sokuban-Clone with Java and Swing2D.

sokuban-clone.png

In April 2016 I decided to rewrite the game in JavaFX.

In this first article I will show the steps how to setup the new project with another GitHub project from me Project-Template-afterburnerfx-Naoghuman and what are the advantages from using this template:

Content

Setup the project

In this section I will explain how to download the project template Project-Template-afterburnerfx-Naoghuman and then after installation into the NetBeans IDE or another from you preferred IDE how to tweak it for the new requirements for the game SokubanFX.

A demo from the minimal project template can be found under https://github.com/Naoghuman/Project-Templates/releases/tag/v0.1.0.

  • Unzip the zip file to a folder from your choose and doubleclick the jar file.
Download the project template

There are two possiblilities to included the project template into your preferred IDE (for me that is NetBeans IDE):

a) Download the source code from https://github.com/Naoghuman/Project-Templates/releases/tag/v0.1.0.

  • Unzip the source code to your workspace and open the project within the NetBeans IDE.

b) Clone the project with https://github.com/Naoghuman/Project-Templates.git

  • Navigate into the new created project Project-Templates.
  • Copy and paste there the project Project-Template-afterburnerfx-Naoghuman to a new destination.
Tweak the project template

In the project root folder is the file Tweak-Project-Template.txt where the steps are listed which are necessary to tweak the template.

Tweak the project (name, properties, packages...)
Update different files like log4j2.xml, application.properties, application.fxml...
  • Update the reference in the tag fx:controller in the file Source Packages/yourpackage/application/application.fxml.
  • Refactore the path from the parameter KEY__APPLICATION__RESOURCE_BUNDLE from the interface IApplicationConfiguration in the folder Source Packages/yourpackage/configuration/.
  • Update the file application.properties in the folder Other Sources/yourpackage/application/ if needed.
  • Update the file log4j2.xml in the default package from Other Sources/ if needed.
Update the JavaDoc (license, autor) if needed
  • If your project license different from General Public License 3.0 which is preselect in the project template then you can refactore the licence in all java files and application.properties with following steps:
    • Change in the project under properties the license.
    • Generate a new java file.
    • Copy and paste the new generated license as needed.
      Another possiblitiy is to use the Replace..., Replace in Projects... function under Edit in the main menu.
  • Rename the autor in all java files and application.properties.
    • Same here -> Replace..., Replace in Projects....
Last steps...

What is the advantages from using this template?

After the preperation from the project template we will have a well configured minimal JavaFX, Maven desktop application with following below listed advantages. Also every library have for it's own great functionalities its the interaction from all libraries in the working project which is the greatest advantage 😇 from the template.

The advantage from the plugin javafx-maven-plugin

generated-jar-file.png

The advantage from the library afterburner.fx

With the library 'afterburner.fx' it's possible to do something like:

final List<CategoryModel> categoryModels = SqlFacade.INSTANCE.getCategorySqlProvider().findAll(matrixModel.getId());
final List<Parent> categoryThumbnailViews = FXCollections.observableArrayList();
for (CategoryModel categoryModel : categoryModels) {
    final CategoryThumbnailView categoryThumbnailView = new CategoryThumbnailView();
    final CategoryThumbnailPresenter categoryThumbnailPresenter = categoryThumbnailView.getRealPresenter();
    categoryThumbnailPresenter.initialize(categoryModel);
    categoryThumbnailViews.add(categoryThumbnailView.getView());
}

One more advantage from the usage from the library afterburner.fx with NetBeans IDE is that you can use a plugin from me which helps zu generate the files:

generated-files-plugin.png

The plugin is available above the Update Center from NetBeans IDE or in the GitHub project: https://github.com/Naoghuman/NetBeansIDE-AfterburnerFX-Plugin/releases

The advantage from the library lib-action

For example have a look here how to register an action:

public class ApplicationPresenter implements Initializable, IActionConfiguration, IRegisterActions {
    ...

    @Override
    public void registerActions() {
        LoggerFacade.INSTANCE.debug(this.getClass(), "Register actions in ApplicationPresenter"); // NOI18N
        
        this.registerOnActionChangeToGameView();
        this.registerOnActionHideMainMenu();
        this.registerOnActionShowMainMenu();
    }

    private void registerOnActionChangeToGameView() {
        LoggerFacade.INSTANCE.debug(this.getClass(), "Register on action change to GameView");
        
        ActionFacade.INSTANCE.register(
                ON_ACTION__CHANGE_TO_GAMEVIEW,
                (ActionEvent event) -> {
                    PreferencesFacade.INSTANCE.putBoolean(
                            IPreviewConfiguration.PROP__KEY_RELEASED__FOR_PREVIEW, 
                            Boolean.FALSE);
        
                    this.onActionChangeToGameView();
                }
        );
    }

    private void onActionChangeToGameView() {
        ...

        final GameView gameView = new GameView();
        final GamePresenter gamePresenter = gameView.getRealPresenter();
        gamePresenter.registerActions();

        ...
    }

    ...
}
  1. With the interface com.github.naoghuman.lib.action.api.IRegisterActions the developer override the method registerActions().
  2. In this method all individual actions from the classApplicationPresenter will be registered.
  3. If the GameView is instantiate, then over the instance from the GamePresenter the method registerActions() will be called and all actions in the class will be registered.
  4. Access to the action can be done with the action-key. In this case is that ON_ACTION__CHANGE_TO_GAMEVIEW (see next code snippet).
public class PreviewPresenter implements Initializable, IActionConfiguration, IRegisterActions {
    ...

    public void onActionStartGame() {
        LoggerFacade.INSTANCE.debug(this.getClass(), "On action start Game"); // NOI18N
        
        if (ptShowNextRandomMap.getStatus().equals(Animation.Status.RUNNING)) {
            ptShowNextRandomMap.stop();
        }
        
        ActionFacade.INSTANCE.handle(ON_ACTION__CHANGE_TO_GAMEVIEW);
    }

    ...
}

It's also possible to define a com.github.naoghuman.lib.action.api.TransferData which can store for example data models. The library is well documented so see for more informations plz: https://github.com/Naoghuman/lib-action

The advantage from the library lib-logger

There are also many additional methods like logging a message at start or end from the application:

public class StartApplication extends Application implements IApplicationConfiguration {

    @Override
    public void init() throws Exception {
        super.init();
        
        final char borderSign = this.getProperty(KEY__APPLICATION__BORDER_SIGN).charAt(0);
        final String message = this.getProperty(KEY__APPLICATION__MESSAGE_START);
        final String title = this.getProperty(KEY__APPLICATION__TITLE) + this.getProperty(KEY__APPLICATION__VERSION);
        LoggerFacade.INSTANCE.message(borderSign, 80, String.format(message, title));
        
        ...
    }

    ...
}

which will log:

2016-05-14 10:50:50,915  INFO  
################################################################################
Start SokubanFX v0.1.0-PROTOTYPE.
################################################################################     [LibLogger]

With the project template comes also a predefined log4j2.xml which can be easily updated for the needs from the project.
See also the section Update different files like log4j2.xml, application.properties, application.fxml...

log4j2-png.png

The library is well documentated, plz see the project ReadMe for more details: https://github.com/Naoghuman/lib-logger

The advantage from the library lib-preferences

preferences-file.png

How does this works?
In SokubanFX is an interface IMapConfiguration defined which contains among others following constants.

public interface IMapConfiguration {
    
    ...
    
    public static final String PROP__ACTUAL_MAP = "PROP__ACTUAL_MAP"; // NOI18N
    public static final int PROP__ACTUAL_MAP__DEFAULT_VALUE = 1;
    
}

This allowed me to store the information which is the actual map from the player. Have he played successful a map, then the counter will increased by one.

How to read this informations can be seen in next example:

public class GamePresenter implements Initializable, IActionConfiguration, IRegisterActions {

    private void loadActualMap() {
        LoggerFacade.INSTANCE.debug(this.getClass(), "Load actual Map"); // NOI18N
        
        final int actualMap = PreferencesFacade.INSTANCE.getInt(
                IMapConfiguration.PROP__ACTUAL_MAP,
                IMapConfiguration.PROP__ACTUAL_MAP__DEFAULT_VALUE);
        
        actualMapModel = MapFacade.INSTANCE.loadMap(actualMap);
    }

    ...
}

and here how to store this information in the file.

public class GamePresenter implements Initializable, IActionConfiguration, IRegisterActions {

    private void evaluateIsMapFinish(boolean isMapFinish) {
        LoggerFacade.INSTANCE.debug(this.getClass(), "Evaluate is Map finish"); // NOI18N
        
        // Keep going :)
        if (!isMapFinish) {
            return;
        }

        // map-level += 1
        final int actualMap = PreferencesFacade.INSTANCE.getInt(
                IMapConfiguration.PROP__ACTUAL_MAP,
                IMapConfiguration.PROP__ACTUAL_MAP__DEFAULT_VALUE);
        PreferencesFacade.INSTANCE.putInt(
                IMapConfiguration.PROP__ACTUAL_MAP,
                actualMap + 1);

        // load next map
        this.loadActualMap();
        this.displayMap();
    }

    ...
}

There are many more functionalitites like add a java.util.prefs.PreferenceChangeListener to the Preferences via the methods forApplication(): Preferences and / or forModule(Class): Preferences.

The library is well documentated, plz see the project ReadMe for more details: https://github.com/Naoghuman/lib-preferences

The advantage from the library lib-properties
  • With the library lib-properties easy registering and accessing from own properties files are possible.
    • Hint: Own properties means properties files which are not automatically included into the Presenters through the library afterburner.fx.

How to register a resource bundle:

public interface IApplicationConfiguration {
    
    ...
    public static final String KEY__APPLICATION__RESOURCE_BUNDLE = "/com/github/naoghuman/sokubanfx/application/application.properties"; // NOI18N
    public static final String KEY__APPLICATION__TITLE = "application.title"; // NOI18N
    public static final String KEY__APPLICATION__VERSION = "application.version"; // NOI18N

}

public class StartApplication extends Application implements IActionConfiguration, IApplicationConfiguration {

    @Override
    public void init() throws Exception {
        super.init();
        
        PropertiesFacade.INSTANCE.register(KEY__APPLICATION__RESOURCE_BUNDLE);
        ...
    }
    ...
}

properties-file.png

Access to a property can be done with:

public class StartApplication extends Application implements IActionConfiguration, IApplicationConfiguration {

    private String getProperty(String propertyKey) {
        return PropertiesFacade.INSTANCE.getProperty(KEY__APPLICATION__RESOURCE_BUNDLE, propertyKey);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        final ApplicationView applicationView = new ApplicationView();
        final ApplicationPresenter applicationPresenter = applicationView.getRealPresenter();
        
        final Scene scene = new Scene(applicationView.getView(), 1280, 720);
        scene.setOnKeyReleased((KeyEvent event) -> {
            this.onKeyReleased(event);
        });
        primaryStage.setTitle(this.getProperty(KEY__APPLICATION__TITLE) + this.getProperty(KEY__APPLICATION__VERSION));
        ...
    }
    ...
}

It's also possible to register and access SystemProperties via the library.

The library is well documentated, when you are interested plz see the project ReadMe for more details: https://github.com/Naoghuman/lib-properties

Conclusion

It seems there are many points which should be updated in the project template. For me it takes 10min and all things are done and the project with above listed advantages 😄 is ready.

And plz don't forget that the greatest advantage in a project is the harmonic interaction from all libraries and components.

About the autor

Let me introduce myself. My name is Peter Rogge and I'm a software developer in Wolfsburg, Germany.

Since 2008 I work by H+D International Group which is an IT- and engineering service provider represented nationally and internationally in over 20 locations with the head-quarters in Wolfsburg, Germany.

In my free time I investigate between 2009 an 2012 some time in NetBeans RCP (Rich Client Platform) development.
See

Since 2011 I change my focus to JavaFX (JavaFX 2.0 - JavaFX 8). Although in 2015 I saw a video from Adam Bien where he mention he would love to write a NetBeans RCP plugin for his library afterburner.fx when he had more time.
So I decided to do this:

Contact

Any question? Some helpful criticism?

Articles in this series

Articles