Samstag, 16. März 2013

Using JavaFX in a Bundle

If a bundle shall provide a user interface, it could create a Stage, add some components and present it on screen. (For instance assume you built some home automation and a fridge monitoring bundle shall present some feedback when the temperature is too high.)

Create and Dispose the Stage

One approach is to create the Stage when the bundle's start method is called. When the bundle is stopped, it should clean up and thus dispose the Stage. Bundles may have an "Activator" which is an implementation of the BundleActivator interface. The interface defines a start method - which is called by the framework when the bundle is started - and a stop method - which is called by the framework when the bundle is stopped.

The OSGi snippets project contains a "bundle_set4jfx" project which contains exactly one class:

public class Activator implements BundleActivator { Logger logger = LoggerFactory.getLogger(Activator.class); Stage stage; @Override public void start(BundleContext context) throws Exception {"Set4Jfx Bundle: start()"); Platform.runLater(new Runnable() { @Override public void run() { stage = new Stage(); BorderPane pane = new BorderPane(); Scene scene = new Scene(pane, 400, 200); pane.setCenter(new Label( "This is a JavaFX Scene in a Stage")); stage.setScene(scene);; } }); } @Override public void stop(BundleContext context) throws Exception {"Set4Jfx Bundle: stop()"); Platform.runLater(new Runnable() { @Override public void run() { stage.close(); } }); } }

In the guitool (*), start the framework, install the bundle file named "bundle_set4jfx" from the files list and start it in the bundles list. (Bundle files are on the right hand side and bundles are on the left hand side in the guitool screen. Bundles appear when bundle files are installed.)

(*) The JavaFX ready guitool must be used. It is located in the example.guitool.fx package.

The bundle starts and a Stage is shown:

Pressing the "Stop" button in the guitool stops the bundle and closes the Stage.

To use JavaFX classes, they must be available to the bundle, otherwise a ClassNotFoundException is thrown. The bundle has a MANIFEST file which among other things contains these three lines:

Bundle-Activator: example.set4jfx.impl.Activator Import-Package: org.osgi.framework, org.slf4j, javafx.application, jav afx.scene, javafx.scene.control, javafx.scene.layout, javafx.stage

The entry Bundle-Activator defines the class which is called when the bundle shall be started or stopped. The entry Import-Package defines the java packages which shall be available to the bundle which in this case must include javafx.application, javafx.scene, etc.

Playing with Import-Package

As a little exercise, you may want to change the Import-Package entry and see what happens. The build scripts create the Import-Package entry from information stored in the file in the project. This file is in the root of project bundle_set4jfx. In the line prj.bundle.import-package=org.osgi.framework, org.slf4j, javafx.application, ... remove the javafx.application package and save the file. Then build the bundle by either running build-bundles.xml or the project's build.xml script. Install the bundle and start it. The bundle information will contain "Activator start error in bundle" and the Eclipse console will show a " java.lang.ClassNotFoundException".


1 Kommentar:

  1. Toll! Danke. Sie haben mir eine gute Idee gegeben. Jetzt will ich das auch unbedingt machen. Habe gerade viel Zeit frei weil mein Business viel erfolgreicher mit Datenraum Anbieter Vergleich geworden ist.