Your Model-View-Whatever pattern in JavaFX

Hi guys !

This topic is not really jMonkey related, but maybe there are JavaFX gurus in there, or more generally, UI expert designer? ^^

I’m bothered with the architecture pattern of the presentation layer of my entity editor for jMonkey. It uses JavaFX.

In a first approach, I used only in-code generated UI. But I’ve found the limit of that : I need more complexe components and a better look & feel. I’m refactoring to a more standard way : MVC !

I have two problems :

  • I don’t like the fx:include approach. It forces me to hardcode things into the fxml code : the name and path of the controller and the name and path of the included fxml. It’s a refactor killer ! I would like to use the fx:root approach, and create custom controls. this way I don’t specifiy anything in the fxml, wich is just a ressource for the custom control class. Refactor is much better but Scene Builder (2.0) is totally lost with that… it can’t resolve any classpath, can’t draw any of your custom control or worst, refuse to run with ClassNotFoundException.

  • My UI elements are Tabs. The problem is that when you create a Tab as root element in Scene Builder, you can’t see anything since a Tab is not a drawble Node itself ! The only solution I’ve found to draw my custom components is to put the Tab control alone in a class, and the content in another. This is not bad, but it works only with the fx:root approach.

My application is young and I want it to be flexible. I would like to avoid creating a monolithic architecture and use Scene Builder as much as possible.

Do you have suggestions?

Hm I usually have the controller side by side with the fxl file in classpath, so the path issue is not that relevant.

I then use a custom controllerfactory, that allows me to attach the controller to sping, and get access to all clientside services.

So i have
View → FXML
Controller → Controller :wink:
Model → Spring Services
(Well and then the rest up to the serverside db)

Pro of this approach is, that i can use a mock controller to test the service stuff.
Tho a model view presenter would be a bit cleaner, it personally find it to much work to be worth in my case.

I never use include, instead I only place a empty region/Group/node to be filled by whatever via code. This makes the view parts better reusable as they do not contains the context anymore, but only the actual elements

Can you tell me more about that? (I don’t know Spring)

Do you use dependency injection to inject your model into the controller?

Well in very short:

@Component marks objects that can be injected
@Autowire marks fields (or setters) that I want to have injected.
An defined xml configures how spring works (eg in my case autoscan for @Components in the classpath, and wiring them)

Please note that spring is very complex at first when you first try to understand it (worse than jme actually, but can usually save quite some time in the long term)

    Starter.ctx = new GenericXmlApplicationContext();
    		Starter.ctx.load("spring/serverEntry.xml");
    
    		final AssetManager assetManager = Starter.initAssetManager();
    
//allow assetmanager to be injected
    		final ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) Starter.ctx).getBeanFactory();
    		beanFactory.registerSingleton(assetManager.getClass().getCanonicalName(), assetManager);
    
    		try {
//do the autowiring
    			Starter.ctx.refresh();
    		} catch (final Exception e) {
    			e.printStackTrace();
    			System.exit(-1);
    		}
    //normal simpleappinit similar logic follows (spring is started within the simpleappinit for example, wiries everything, then proceeds with the actual startup of your custom stuff.
    		Starter.ctx.getBean(IServerApplication.class).startApplication();

and the reduced xml, note that i also use jpa, spring security ect for parts so the initial definition is a bit bloated:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
			http://www.springframework.org/schema/tx 			http://www.springframework.org/schema/tx/spring-tx.xsd
	 		http://www.springframework.org/schema/data/jpa     	http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
            http://www.springframework.org/schema/beans 		http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop 			http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context 		http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/util 			http://www.springframework.org/schema/util/spring-util.xsd">

	<aop:aspectj-autoproxy proxy-target-class="true" />
	<tx:annotation-driven />
	<context:annotation-config />
	<context:component-scan base-package="de.visiongamestudios" />
</beans>

Spring is inheritance aware, eg if I request a assetmanager, but at runtime it is actually a Desktopassetmanager it understands this. This allows to have some shared interface projects, and no need to do endless stichting via setX or getY to bring everything together.

1 Like

Are there consequences in memory consumption and performances linked to using spring for a game? Or are they negligible? I used spring for a couple years and made it run with jme (and netbeans etc)… just wondering if you have any idea of the costs of using it?
I used spring but for a big system on a big server… is it ok on a phone for example?

In JavaLand, Spring is the heaviest of currents DI framework, it’s not recommended for android.
My suggestion use dagger or dagger 2, less feature than spring, if some feature is missing use Guice (it’s a runtime DI like Spring). Or do manual DI ;-).

1 Like

Dagger 2 looks to fit my needs perfectly. If I find the courage, I’ll refactor to use it.

I tried dagger recently for my daywork gwt project, at least do not use it with eclipse, it created tons of problems with failing incremental compiling, might work better in netbeans or intellij.
(Reason is, that if i change class a, for class b a different wiring is required, but since only class a is recompiled by the incremental compiler , the annotation processor is never called on class b)

Anyway the overhead for spring in my case is 0 at runtime, as it just pushes objects where they belong,
and around 1-2 seconds additional startup time. I have longer loading times for the complex fxml ui’s

It has the nice benefit of being a actual business world compatible knowledge as well, while some other frameworks are rarely used for paying projects :slight_smile:

1 Like