java - Launching JavaFX 2 with Spring boot -
i trying combine new application javafx 2 , spring boot, far simple (like hello world) app isn't running because of "root null" in mainpanecontroller.
mainpanecontroller class:
public class mainpanecontroller implements initializable { public static final string view = "/fxml/scene.fxml"; @fxml private node root; @fxml private label label; @postconstruct public void init() { } public node getroot() { return root; } @fxml private void handlebuttonaction(actionevent event) { system.out.println("you clicked me!"); label.settext("hello world!"); } @override public void initialize(url url, resourcebundle rb) { // todo } } my main class fxbootapplication:
@springbootapplication public class fxbootapplication extends application {
private static string[] args; @override public void start(final stage stage) throws exception { //parent root = fxmlloader.load(getclass().getresource("/fxml/scene.fxml")); // bootstrap spring context here. applicationcontext context = springapplication.run(fxbootapplication.class, args); mainpanecontroller mainpanecontroller = context.getbean(mainpanecontroller.class); scene scene = new scene((parent) mainpanecontroller.getroot()); // error here //scene scene = new scene(root); //scene.getstylesheets().add("/styles/styles.css"); stage.settitle("javafx , maven"); stage.setscene(scene); stage.show(); } /** * main() method ignored in correctly deployed javafx application. * main() serves fallback in case application can not * launched through deployment artifacts, e.g., in ides limited fx * support. netbeans ignores main(). * * @param args command line arguments */ public static void main(string[] args) { fxbootapplication.args = args; launch(args); } } and applicationconfiguration class: @configuration public class applicationconfiguration {
@bean public mainpanecontroller mainpanecontroller() throws ioexception { mainpanecontroller mpc = (mainpanecontroller) loadcontroller(mainpanecontroller.view); return mpc; } public <t> t loadcontroller(string url) throws ioexception { try (inputstream fxmlstream = getclass().getresourceasstream(url)) { fxmlloader loader = new fxmlloader(getclass().getresource(url)); //fxmlloader.load(url); loader.load(fxmlstream); return loader.getcontroller(); } } } error while trying root scene controller.getroot();
what missing here? followed solution here -> javafx fxml - how use spring di nested custom controls? not working me @ all. should somehow initialize root before?
unfortunately don't find link solution, works me, anymore... but: have code, tested extend.
first need application class:
package eu.dzim.yatafx; import org.apache.logging.log4j.logmanager; import org.apache.logging.log4j.logger; import org.springframework.beans.factory.annotation.autowired; import org.springframework.boot.commandlinerunner; import org.springframework.boot.springapplication; import org.springframework.boot.autoconfigure.enableautoconfiguration; import org.springframework.context.configurableapplicationcontext; import org.springframework.context.annotation.componentscan; import org.springframework.context.annotation.configuration; import eu.dzim.yatafx.model.app.applicationmodel; import eu.dzim.yatafx.spring.service.fxmlloaderservice; import eu.dzim.yatafx.util.utils; import eu.dzim.yatafx.util.res.stringresource; import javafx.application.application; import javafx.application.platform; import javafx.fxml.fxmlloader; import javafx.scene.scene; import javafx.scene.layout.pane; import javafx.stage.stage; @configuration @enableautoconfiguration @componentscan public class yatafxapplication extends application implements commandlinerunner { private static final logger log = logmanager.getlogger(filesyncfxapplication.class); @override public void run(string... args) { // call prior real application starts? } private static string[] savedargs; // locally stored spring boot application context private configurableapplicationcontext applicationcontext; // need override fx init process spring boot @override public void init() throws exception { // set thread name thread.currentthread().setname("main"); // log.debug("init javafx application"); applicationcontext = springapplication.run(getclass(), savedargs); applicationcontext.getautowirecapablebeanfactory().autowirebean(this); } // ... , close our context on stop of fx part @override public void stop() throws exception { // log.debug("stop javafx application"); super.stop(); applicationcontext.close(); } protected static void launchapp(class<? extends filesyncfxapplication> appclass, string[] args) { filesyncfxapplication.savedargs = args; application.launch(appclass, args); } @autowired private fxmlloaderservice mfxmlloaderservice; @autowired private applicationmodel mapplicationmodel; @override public void start(stage primarystage) { // set thread name thread.currentthread().setname("main-ui"); try { fxmlloader loader = mfxmlloaderservice.getloader(utils.getfxmlresource("root"), stringresource.getresourcebundle()); pane root = loader.load(); scene scene = new scene(root, 1200, 800); scene.getstylesheets().add("/eu/dzim/filesyncfx/ui/application.css"); primarystage.setscene(scene); primarystage.setoncloserequest(windowevent -> { log.debug("tear down javafx application"); // mapplicationmodel.setloggedin(!mloginservice.logout()); // orderly shut down fx platform.exit(); // but: there might still daemon thread left on okhttp (some async dispatcher) // assume fine , call system.exit(0) system.exit(0); }); primarystage.show(); } catch (exception e) { log.error(e.getmessage(), e); } } public static void main(string[] args) throws exception { // springapplication.run(samplesimpleapplication.class, args); savedargs = args; application.launch(filesyncfxapplication.class, args); } } i used org.springframework.boot:spring-boot-starter-parent:1.3.3.release base.
note fxmlloaderservice interface autowired here:
package eu.dzim.yatafx.spring.service; import java.net.url; import java.util.resourcebundle; import javafx.fxml.fxmlloader; public interface fxmlloaderservice { fxmlloader getloader(); fxmlloader getloader(url location); fxmlloader getloader(url location, resourcebundle resourcebundle); } the implementation looks this:
package eu.dzim.yatafx.spring.service.impl; import java.net.url; import java.util.resourcebundle; import javax.annotation.postconstruct; import javax.annotation.predestroy; import org.apache.logging.log4j.logmanager; import org.apache.logging.log4j.logger; import org.springframework.beans.factory.annotation.autowired; import org.springframework.context.configurableapplicationcontext; import org.springframework.context.annotation.scope; import org.springframework.stereotype.component; import eu.dzim.yatafx.spring.service.fxmlloaderservice; import javafx.fxml.fxmlloader; import javafx.util.callback; @component @scope("singleton") public class fxmlloaderserviceimpl implements fxmlloaderservice { private static final logger log = logmanager.getlogger(fxmlloaderserviceimpl.class); @autowired private configurableapplicationcontext context; @postconstruct private void postconstruct() { log.debug("postconstruct: set " + getclass().getname()); } @override public fxmlloader getloader() { fxmlloader loader = new fxmlloader(); loader.setcontrollerfactory(new callback<class<?>, object>() { @override public object call(class<?> param) { return context.getbean(param); } }); return loader; } @override public fxmlloader getloader(url location) { fxmlloader loader = new fxmlloader(location); loader.setcontrollerfactory(new callback<class<?>, object>() { @override public object call(class<?> param) { return context.getbean(param); } }); return loader; } @override public fxmlloader getloader(url location, resourcebundle resourcebundle) { fxmlloader loader = new fxmlloader(location, resourcebundle); loader.setcontrollerfactory(new callback<class<?>, object>() { @override public object call(class<?> param) { return context.getbean(param); } }); return loader; } @predestroy private void predestroy() { log.debug("predestroy: tear down " + getclass().getname()); } } the usage displayed in application class: @autowire service , create sub-views there. since rely exclusivly on fxml, 1 importand me, since want use nice di stuff in controllers.
best example global application, wich holds javafx properties attach in controller classes.
while shown application more stub (the application , fxml service), had fun project used approach in concurrency parallel developed web application, resting on "micro"service developed @ work.
hope code enough example work on side. please ask, if have more questions.
cheers, daniel
edit: think mistake in code part in fxml service. have injected configurableapplicationcontext use create controller from. need controllerfactory this.
there third party samples assist javafx , spring boot integration:
Comments
Post a Comment