Views
3 months ago

tornadofx-guide

Scopes The edit function

Scopes The edit function creates a new Scope and injects a PersonModel configured with the selected user into that scope. Finally, it retrieves a PersonEditor in the context of the new scope and opens a new window. When the PersonEditor is initialized, it will look up a PersonModel via injection. The default context for inject and find is always the scope that created the component, so it will look in the personScope we just created. val model: PersonModel by inject() Breaking Out of the Current Scope When no scope is defined, injectable resources are looked up in the default scope. There is an item representing that scope called DefaultScope . In the above example, the editor might have called out to a PersonController to perform a save operation in a database or via a REST call. This PersonController is most probably stateless, so there is no need to create a separate controller for each edit window. To access the same controller in all editor windows, we supply the scope we want to find the controller in: val controller: PersonController by inject(DefaultScope) This effectively makes the PersonController a true singleton object again, with only a single instance in the whole application. The default scope for new injected objects are always the current scope for the component that calls inject or find , and consequently all objects created in that injection run will belong to the supplied scope. Keeping State in Scopes In the previous example we used injection on a scope level to get a hold of our resources. It is also possible to subclass Scope and put arbitrary data in there. Each TornadoFX Component has a scope property that gives you access to that scope instance. You can even override it to provide the custom subclass so you don't need to cast it on every occasion: override val scope = super.scope as PersonScope 214

Scopes Now whenever you access the scope property from your code, it will be of type PersonScope . It now contains a PersonModel that will only be available to this scope: class PersonScope : Scope() { } val model = PersonModel() Let's change our previous example slightly to access the model inside the scope instead of using injection. First we change the editPerson function: fun editPerson(person: Person) { val editScope = PersonScope() editScope.model.item = person find(PersonEditor::class, editScope).openWindow() } The custom scope already has an instance of PersonModel , so we just configure the item for that scope and open the editor. Now the editor can override the type of scope and access the model: // Cast scope override val scope = super.scope as PersonScope // Extract our view model from the scope val model = scope.model Both approaches work equally well, but depending on your use case you might prefer one over the other. Global application scope As we hintet to initially, you can run multiple applications in the same JVM and keep them completely separate by using scopes. By default, JavaFX does not support multi tenancy, and can only start a single JavaFX application per JVM, but new technologies are emerging that leverages multitenancy and will even expose your JavaFX based applications to the web. One such technology is JPro.io, and TornadoFX supports multitenancy for JPro applications by leveraging scopes. There is no special JPro classes in TornadoFX, but supporting JPro is very simple by leveranging scopes: Using TornadoFX with JPro 215

Guide
GUIDE
Guide
GUIDE
Guide
Guide
GUIDE
Guide
GUIDE
Guide
GUIDE
GUIDE