Views
8 months ago

tornadofx-guide

OSGi You can provide

OSGi You can provide type-safe stylesheets to other TornadoFX bundles by registering them in an Activator : class Activator : BundleActivator { override fun start(context: BundleContext) { context.registerStylesheet(Styles::class) } } override fun stop(context: BundleContext) { } Using OSGi Declarative Services the registration looks like this: @Component class StyleRegistration : StylesheetProvider { override val stylesheet = Styles::class } Whenever this bundle is loaded, every active View will have this stylesheet applied. When the bundle is unloaded, the stylesheet is automatically removed. If you want to provide multiple stylesheets based on the same style classes, it is a good idea to create one bundle that exports the cssclass definitions, so that your Views can reference these styles, and the stylesheet bundles can create selectors based on them. Dynamic Views A cool aspect of OSGi is the ability to have UI elements pop up when they become available. A typical use case could be a "dashboard" application. In this example, the base application bundle contains a View that can hold other Views, and tells the TornadoFX OSGi Runtime that it would like to automatically embed Views if they meet certain criteria. For instance, we can create a View that contains a VBox . We tell the TornadoFX OSGi Runtime that we would like to have other Views embedded into it if they are tagged with the discriminator dashboard: 208

OSGi class Dashboard : View() { override val root = VBox() } init { title = "Dashboard Application" addViewsWhen { it.discriminator == "dashboard" } } If the addViewsWhen function returns true, the View is added to the VBox . To offer up Views to this Dashboard, another bundle would declare that it wants to export it's View by setting the dashboard discriminator. Here we register a fictive MusicPlayer view to be docked into the dashboard when it's bundle becomes active. class Activator : BundleActivator { override fun start(context: BundleContext) { context.registerView(MusicPlayer::class, "dashboard") } } override fun stop(context: BundleContext) { } Again, the OSGi Declarative Services way of exporting the View would look like this: @Component class MusicPlayerRegistration : ViewProvider { override val discriminator = "dashboard" override fun getView() = find(MusicPlayer::class) } The addViewsWhen function is smart enough to inspect the VBox and find out how to add the child View it was presented. It can also figure out that if you call the function on a TabPane it would create a new Tab and set the title to the child View title etc. If you would like to do something custom with the presented Views, you can return false from the function so that the child View will not be added automatically and then do whatever you want with it. Even though the Tab example is supported out of the box, you could do it explicitly like this: 209

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