I can't remember where I found the following allowing me to very simply
launch OSGI-JAVAFX apps, but I give here a skeleton that I use everywhere.
The point is that I'm using NetBeans platform, and Ant, (it seems to be
also your case) because I can't be be connected to www.
The local Ant build's file for NetBeans is changed according to:
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="default" basedir=".">
<description>Builds, tests, and runs the project test.</description>
<import file="nbproject/build-impl.xml"/>
<property name="felix.dir" value="../../osgi_lib/tasks"/>
<property name="test.dir" value=".."/>
<taskdef name="ipojo"
classname="org.apache.felix.ipojo.task.IPojoTask"
classpath="${felix.dir}/org.apache.felix.ipojo.ant-1.12.1.jar"/>
<taskdef resource="aQute/bnd/ant/taskdef.properties"
classpath="${felix.dir}/bnd-1.50.0.jar"/>
<target depends="init,compile,-pre-pre-jar" name="-do-jar">
<bnd
classpath="${build.dir}/classes"
files="bind.bnd"
output="${dist.jar}"
failok="false"
exceptions="true" />
<ipojo input="${dist.jar}" classpath="${javac.classpath}" />
<copy file="${dist.jar}" todir="${test.dir}/bundles"/>
</target>
</project>
Futhermore, in the config file I added these lines:
# To append packages to the default set of exported system packages,
# set this value.
org.osgi.framework.system.packages.extra=javafx.application;version=0.0.0, \
com.sun.browser.plugin; version=0.0.0, \
com.sun.deploy.uitoolkit.impl.fx; version=0.0.0, \
com.sun.deploy.uitoolkit.impl.fx.ui; version=0.0.0, \
com.sun.deploy.uitoolkit.impl.fx.ui.resources; version=0.0.0, \
com.sun.deploy.uitoolkit.impl.fx.ui.resources.image; version=0.0.0, \
com.sun.glass.events; version=0.0.0, \
com.sun.glass.ui; version=0.0.0, \
com.sun.glass.ui.delegate; version=0.0.0, \
com.sun.glass.ui.gtk; version=0.0.0, \
com.sun.glass.ui.mac; version=0.0.0, \
com.sun.glass.ui.win; version=0.0.0, \
com.sun.glass.ui.x11; version=0.0.0, \
com.sun.glass.utils; version=0.0.0, \
com.sun.javafx; version=0.0.0, \
com.sun.javafx.animation; version=0.0.0, \
com.sun.javafx.animation.transition; version=0.0.0, \
com.sun.javafx.applet; version=0.0.0, \
com.sun.javafx.application; version=0.0.0, \
com.sun.javafx.beans; version=0.0.0, \
com.sun.javafx.beans.annotations; version=0.0.0, \
com.sun.javafx.beans.event; version=0.0.0, \
com.sun.javafx.binding; version=0.0.0, \
com.sun.javafx.charts; version=0.0.0, \
com.sun.javafx.collections; version=0.0.0, \
com.sun.javafx.collections.annotations; version=0.0.0, \
com.sun.javafx.collections.transformation; version=0.0.0, \
com.sun.javafx.css; version=0.0.0, \
com.sun.javafx.css.converters; version=0.0.0, \
com.sun.javafx.css.parser; version=0.0.0, \
com.sun.javafx.cursor; version=0.0.0, \
com.sun.javafx.effect; version=0.0.0, \
com.sun.javafx.embed; version=0.0.0, \
com.sun.javafx.event; version=0.0.0, \
com.sun.javafx.font; version=0.0.0, \
com.sun.javafx.fxml; version=0.0.0, \
com.sun.javafx.fxml.builder; version=0.0.0, \
com.sun.javafx.fxml.expression; version=0.0.0, \
com.sun.javafx.geom; version=0.0.0, \
com.sun.javafx.geom.transform; version=0.0.0, \
com.sun.javafx.iio; version=0.0.0, \
com.sun.javafx.iio.bmp; version=0.0.0, \
com.sun.javafx.iio.common; version=0.0.0, \
com.sun.javafx.iio.gif; version=0.0.0, \
com.sun.javafx.iio.jpeg; version=0.0.0, \
com.sun.javafx.iio.png; version=0.0.0, \
com.sun.javafx.image; version=0.0.0, \
com.sun.javafx.image.impl; version=0.0.0, \
com.sun.javafx.jmx; version=0.0.0, \
com.sun.javafx.logging; version=0.0.0, \
com.sun.javafx.menu; version=0.0.0, \
com.sun.javafx.perf; version=0.0.0, \
com.sun.javafx.property; version=0.0.0, \
com.sun.javafx.property.adapter; version=0.0.0, \
com.sun.javafx.robot; version=0.0.0, \
com.sun.javafx.robot.impl; version=0.0.0, \
com.sun.javafx.runtime; version=0.0.0, \
com.sun.javafx.runtime.async; version=0.0.0, \
com.sun.javafx.runtime.eula; version=0.0.0, \
com.sun.javafx.scene; version=0.0.0, \
com.sun.javafx.scene.control; version=0.0.0, \
com.sun.javafx.scene.control.behavior; version=0.0.0, \
com.sun.javafx.scene.control.skin; version=0.0.0, \
com.sun.javafx.scene.control.skin.caspian; version=0.0.0, \
com.sun.javafx.scene.control.skin.resources; version=0.0.0, \
com.sun.javafx.scene.input; version=0.0.0, \
com.sun.javafx.scene.layout.region; version=0.0.0, \
com.sun.javafx.scene.paint; version=0.0.0, \
com.sun.javafx.scene.shape; version=0.0.0, \
com.sun.javafx.scene.text; version=0.0.0, \
com.sun.javafx.scene.transform; version=0.0.0, \
com.sun.javafx.scene.traversal; version=0.0.0, \
com.sun.javafx.scene.web; version=0.0.0, \
com.sun.javafx.scene.web.behavior; version=0.0.0, \
com.sun.javafx.scene.web.skin; version=0.0.0, \
com.sun.javafx.sg; version=0.0.0, \
com.sun.javafx.sg.prism; version=0.0.0, \
com.sun.javafx.stage; version=0.0.0, \
com.sun.javafx.tk; version=0.0.0, \
com.sun.javafx.tk.desktop; version=0.0.0, \
com.sun.javafx.tk.quantum; version=0.0.0, \
com.sun.javafx.util; version=0.0.0, \
com.sun.media.jfxmedia; version=0.0.0, \
com.sun.media.jfxmedia.control; version=0.0.0, \
com.sun.media.jfxmedia.effects; version=0.0.0, \
com.sun.media.jfxmedia.events; version=0.0.0, \
com.sun.media.jfxmedia.locator; version=0.0.0, \
com.sun.media.jfxmedia.logging; version=0.0.0, \
com.sun.media.jfxmedia.track; version=0.0.0, \
com.sun.media.jfxmediaimpl; version=0.0.0, \
com.sun.media.jfxmediaimpl.platform; version=0.0.0, \
com.sun.media.jfxmediaimpl.platform.gstreamer; version=0.0.0, \
com.sun.media.jfxmediaimpl.platform.java; version=0.0.0, \
com.sun.media.jfxmediaimpl.platform.osx; version=0.0.0, \
com.sun.openpisces; version=0.0.0, \
com.sun.prism; version=0.0.0, \
com.sun.prism.camera; version=0.0.0, \
com.sun.prism.d3d; version=0.0.0, \
com.sun.prism.d3d.hlsl; version=0.0.0, \
com.sun.prism.image; version=0.0.0, \
com.sun.prism.impl; version=0.0.0, \
com.sun.prism.impl.packrect; version=0.0.0, \
com.sun.prism.impl.paint; version=0.0.0, \
com.sun.prism.impl.ps; version=0.0.0, \
com.sun.prism.impl.shape; version=0.0.0, \
com.sun.prism.j2d; version=0.0.0, \
com.sun.prism.j2d.paint; version=0.0.0, \
com.sun.prism.paint; version=0.0.0, \
com.sun.prism.ps; version=0.0.0, \
com.sun.prism.render; version=0.0.0, \
com.sun.prism.shader; version=0.0.0, \
com.sun.prism.shape; version=0.0.0, \
com.sun.prism.tkal; version=0.0.0, \
com.sun.prism.util.tess; version=0.0.0, \
com.sun.prism.util.tess.impl.tess; version=0.0.0, \
com.sun.scenario; version=0.0.0, \
com.sun.scenario.animation; version=0.0.0, \
com.sun.scenario.animation.shared; version=0.0.0, \
com.sun.scenario.effect; version=0.0.0, \
com.sun.scenario.effect.impl; version=0.0.0, \
com.sun.scenario.effect.impl.hw; version=0.0.0, \
com.sun.scenario.effect.impl.hw.d3d; version=0.0.0, \
com.sun.scenario.effect.impl.hw.d3d.hlsl; version=0.0.0, \
com.sun.scenario.effect.impl.prism; version=0.0.0, \
com.sun.scenario.effect.impl.prism.ps; version=0.0.0, \
com.sun.scenario.effect.impl.prism.sw; version=0.0.0, \
com.sun.scenario.effect.impl.state; version=0.0.0, \
com.sun.scenario.effect.impl.sw; version=0.0.0, \
com.sun.scenario.effect.impl.sw.java; version=0.0.0, \
com.sun.scenario.effect.impl.sw.sse; version=0.0.0, \
com.sun.scenario.effect.light; version=0.0.0, \
com.sun.t2k; version=0.0.0, \
com.sun.webpane.perf; version=0.0.0, \
com.sun.webpane.platform; version=0.0.0, \
com.sun.webpane.platform.event; version=0.0.0, \
com.sun.webpane.platform.graphics; version=0.0.0, \
com.sun.webpane.sg; version=0.0.0, \
com.sun.webpane.sg.prism; version=0.0.0, \
com.sun.webpane.sg.prism.resources; version=0.0.0, \
com.sun.webpane.sg.prism.theme; version=0.0.0, \
com.sun.webpane.sg.theme; version=0.0.0, \
com.sun.webpane.webkit; version=0.0.0, \
com.sun.webpane.webkit.dom; version=0.0.0, \
com.sun.webpane.webkit.network; version=0.0.0, \
com.sun.webpane.webkit.network.about; version=0.0.0, \
com.sun.webpane.webkit.network.data; version=0.0.0, \
com.sun.webpane.webkit.unicode; version=0.0.0, \
javafx.animation; version=0.0.0, \
javafx.beans; version=0.0.0, \
javafx.beans.binding; version=0.0.0, \
javafx.beans.property; version=0.0.0, \
javafx.beans.property.adapter; version=0.0.0, \
javafx.beans.value; version=0.0.0, \
javafx.collections; version=0.0.0, \
javafx.collections.transformation; version=0.0.0, \
javafx.concurrent; version=0.0.0, \
javafx.embed.swing; version=0.0.0, \
javafx.embed.swt; version=0.0.0, \
javafx.event; version=0.0.0, \
javafx.fxml; version=0.0.0, \
javafx.geometry; version=0.0.0, \
javafx.scene; version=0.0.0, \
javafx.scene.canvas; version=0.0.0, \
javafx.scene.chart; version=0.0.0, \
javafx.scene.control; version=0.0.0, \
javafx.scene.control.cell; version=0.0.0, \
javafx.scene.effect; version=0.0.0, \
javafx.scene.image; version=0.0.0, \
javafx.scene.input; version=0.0.0, \
javafx.scene.layout; version=0.0.0, \
javafx.scene.media; version=0.0.0, \
javafx.scene.paint; version=0.0.0, \
javafx.scene.shape; version=0.0.0, \
javafx.scene.text; version=0.0.0, \
javafx.scene.transform; version=0.0.0, \
javafx.scene.web; version=0.0.0, \
javafx.stage; version=0.0.0, \
javafx.util; version=0.0.0, \
javafx.util.converter; version=0.0.0, \
netscape.javascript; version=0.0.0
for JAVAFX classes to be imported. Also note that sometimes, JAVAFX classes
that are not in your java file's import section, must explicitly appeared in
the import-package's declaration of the bnd file. However Felix flags these
missing classes at run time.
*I) StageService bundle*
The first bundle is a simple service
package em.widget.stage.service;
import javafx.stage.Stage;
public interface StageService {
public String STAGE_NAME = "stage.name";
public Stage getStage();
}
with a simple method getStage(). Each JAVAFX widget (a Stage in JAVAFX
defining a "window" on the screen) implements this service. Its name is the
service property's String defined by STAGE_NAME.
*II) JAVAFX Launching bundle*
The following lines are the JAVAFX launcher. They implement a StageService
with no name.
package em.widget.stage.impl;
import em.widget.stage.service.StageService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.stage.Stage;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Provides;
@Component
@Provides
public class StageImpl extends Application implements StageService {
private static Stage pstage = null;
private static Thread t;
/**
* The local Stage is sets.
*
* @param primaryStage The stage
* @throws Exception
*/
@Override
public void start(Stage primaryStage) throws Exception {
pstage = primaryStage;
synchronized (t) {
t.notify();
}
}
@Override
public Stage getStage() {
if (pstage == null) {
Executors.defaultThreadFactory().newThread(() -> {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
launch();
}).start();
t = Thread.currentThread();
synchronized (t) {
try {
t.wait();
} catch (InterruptedException ex) {
Logger.getLogger(StageService.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
return pstage;
}
}
*III) Defining your widget.*
You have now to write your widgets like the following one which is a JAVAFX
interface to connection's parameters. The fxml file is within the package
directory, and the four lines below DBWidget's creator take into account the
special OSGI class loader. Everything else is usual in JAVAFX apps.
package em.widget.connection.impl;
import em.persistence.service.ConnectionService;
import em.widget.stage.service.StageService;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Context;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Requires;
import org.apache.felix.ipojo.annotations.ServiceProperty;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import em.widget.datas.service.DatasWidgetService;
import org.osgi.framework.BundleException;
@Component
@Provides
public class ConnectionWidgetImpl implements StageService {
@FXML
TextField adminuser, user, dbname, ip, port, threadnumber;
@FXML
PasswordField adminpassword, password;
@FXML
Button button1;
@Context
BundleContext context;
@Requires
ConnectionService connectionService;
@ServiceProperty(name = STAGE_KIND)
String kind;
Stage theStage;
Boolean connected = false;
DatasWidgetService datasWidgetService;
ChangeListener<String> threadsNumberListener = new
ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable,
String oldValue, String newValue) {
try {
double t = Integer.valueOf(newValue);
if (t <= 0) {
threadnumber.setText(oldValue);
}
} catch (NumberFormatException nfe) {
threadnumber.setText("1");
}
}
};
public ConnectionWidgetImpl() {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
FXMLLoader.setDefaultClassLoader(getClass().getClassLoader());
fxmlLoader.setLocation(getClass().getResource("Widget.fxml"));
// Avoid the controller in fxml file, and declares itself as the
controller
fxmlLoader.setController(this);
theStage = new Stage();
theStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
try {
ServiceReference[] sr =
context.getServiceReferences(StageService.class.getName(), "(" +
StageService.STAGE_KIND + "=*)");
for (ServiceReference sr1 : sr) {
((StageService)
context.getService(sr1)).getStage().close();
}
context.getBundle(0).stop();
} catch (InvalidSyntaxException | BundleException ex) {
Logger.getLogger(ConnectionWidgetImpl.class.getName()).log(Level.SEVERE,
null, ex);
}
}
});
try {
theStage.setTitle("DataBase Connection");
theStage.setScene(new Scene(fxmlLoader.load()));
} catch (IOException ex) {
Logger.getLogger(ConnectionWidgetImpl.class.getName()).log(Level.SEVERE,
null, ex);
}
adminuser.textProperty().bindBidirectional(connectionService.getAdminUser());
ip.textProperty().bindBidirectional(connectionService.getIP());
port.textProperty().bindBidirectional(connectionService.getPort());
user.textProperty().bindBidirectional(connectionService.getUser());
dbname.textProperty().bindBidirectional(connectionService.getDBName());
adminpassword.textProperty().bindBidirectional(connectionService.getAdminPassword());
password.textProperty().bindBidirectional(connectionService.getPassword());
threadnumber.textProperty().addListener(threadsNumberListener);
threadnumber.textProperty().bindBidirectional(connectionService.getThreadsNumber());
button1.setText("Connect");
button1.setStyle("-fx-color:tomato");
}
@Override
public Stage getStage() {
return theStage;
}
@FXML
public void connect(ActionEvent ae) {
......
}
*IV) Starting your app*
After calling "mainStageService.getStage();" in the following code, the
JAVAFX thread is running, and it's simple for the previous widget to be
displayed on screen.
package em.test;
import java.util.Properties;
import org.apache.felix.ipojo.ConfigurationException;
import org.apache.felix.ipojo.Factory;
import org.apache.felix.ipojo.MissingHandlerException;
import org.apache.felix.ipojo.UnacceptableConfiguration;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Context;
import org.apache.felix.ipojo.annotations.Instantiate;
import org.apache.felix.ipojo.annotations.Requires;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import em.widget.stage.service.StageService;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
@Component
@Instantiate
public class DBWidget {
@Context
BundleContext context;
@Requires(filter =
"(factory.name=em.widget.connection.impl.ConnectionWidgetImpl)")
Factory persistenceStageFactory;
public DBWidget() {
// Creating the mainstage object
mainStageFactory.createComponentInstance(null);
ServiceReference<StageService> stageServiceRef =
context.getServiceReference(StageService.class);
StageService mainStageService = (StageService)
context.getService(stageServiceRef);
// Then start the FX thread
mainStageService.getStage();
// Creates a widget on FX thread.
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
Properties d = new Properties();
d.put(StageService.STAGE_KIND, "DBConnect");
persistenceStageFactory.createComponentInstance(d);
ServiceReference[] sr =
context.getServiceReferences(StageService.class.getName(), "(" +
StageService.STAGE_KIND + "=DBConnect)");
StageService persistentStageService = (StageService)
context.getService(sr[0]);
// show the connect widget
persistentStageService.getStage().show();
} catch (UnacceptableConfiguration | MissingHandlerException
| ConfigurationException | InvalidSyntaxException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE,
null, ex);
}
}
});
.......
--
View this message in context:
http://apache-felix.18485.x6.nabble.com/Re-Felix-and-JavaFX-tp5021784p5021880.html
Sent from the Apache Felix - Users mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]