Freitag, 15. März 2013

guitool with JavaFX

Similar to a Swing based guitool, the osgisnippets project contains a JavaFX 2 based guitool. It is located in the project guitool in the package example.guitool.fx . The package is essentially a copy of example.guitool with adjustments to make it work with JavaFX.

Embedding OSGi into JavaFX

The class OSGiFwLoader takes care of the main work of starting and stopping the OSGi framework and managing bundles. In Embedding OSGi the main features of the OSGiFwLoader class are described. There is one major difference between the version there and the JavaFX related version.

The goal is to load bundles which use JavaFX components. To do that, the bundle imports javafx.* packages. These packages must be made available and this is done in OSGiFwLoader.prepareConfigMap():

private void prepareConfigMap(Map<Object, Object> configMap) { // List the packages which shall be exported by the System Bundle. ... configMap.put( Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "example.set2appapi.api, " + "example.set2cmdapi.api, " + "javafx.application, " + "javafx.scene, " + "javafx.scene.control, " + "javafx.scene.layout, " + "javafx.stage, " + "org.slf4j"); // Each time the OSGi Framework starts, it shall clean up its // storage. I decided to do that, so one gets a clean environment // each time. configMap.put( Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT); // This is for application provided BundleActivators: List<Object> list = new ArrayList<>(); // fillSystemBundleActivators(list); configMap.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list); }

The bold lines let these JavaFX packages be exported by the system bundle and are thus available to the bundles which use JavaFX components. (If further packages are required, they need to be added to the list of packages.)

The JavaFX GUI Tool

The JavaFX gui tool shall be able to start bundles which display Swing components. As described in JavaFX and Swing (on a Mac) some extra steps are necessary to allow Swing components to be used in JavaFX. Instead of the typical Application.launch() call, Swing is started first and JavaFX is embedded there:

public static void main(final String[] args) { startJFXPanel(args); } private static void startJFXPanel(final String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { final JFrame mainFrame = new JFrame("gui tool (s/fx)"); final JFXPanel jfxPanel = new JFXPanel(); mainFrame.getContentPane().add(jfxPanel); mainFrame.setTitle("OSGi Snippets GUI Tool (s/fx)"); mainFrame.setSize(800, 600); mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); Platform.runLater(new Runnable() { @Override public void run() { MainFXUI fxui = new MainFXUI(); try { fxui.start(jfxPanel, mainFrame); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } catch (Exception e) { e.printStackTrace(); } } }); }

Doing these things on a Mac was leading to more issues than under Windows. If it is good enough under the circumstances, the following start method may be used too:

private static void startAWT(String[] args) { System.setProperty("javafx.macosx.embedded", "true"); java.awt.Toolkit.getDefaultToolkit(); Application.launch(MainFXUI.class, args); }

Things are changing a lot currently so this jumping through hoops may not be necessary in the future (JavaFX 1.x reaches EOL, JavaFX 2.x in JDK7 is out for a while, JavaFX 8 is available as early access and parts of JavaFX already went Open Source).


Keine Kommentare:

Kommentar veröffentlichen