6 Replies Latest reply: Oct 31, 2013 8:38 AM by Liang123 RSS

    How Java call JavaFX?

    Liang123

      I need call JavaFX from Java, Java needs to load the entry method start(Stage stage) of JavaFX, who can give me a help?

      Thank you very muvh!

        • 1. Re: How Java call JavaFX?
          James_D
          Application.launch(MyApp.class, arg0, arg1, ...)
          

           

          where MyApp is your application class (a subclass of Application, defining a start method).

           

          arg0, arg1, etc are any arguments you need to pass. You can omit these arguments if you don't need them.

          • 2. Re: How Java call JavaFX?
            Liang123

            James_D ,

            I tried your solution, it can work, but I found some questions.

            1. When I use "run file" from Java class, it starts from Java; When I use "run project", it starts from JavaFX not from Java;

            2. When I use "run project", GUI can change ProgressBar state; When I use "run file" in Java class, GUI cannot change ProgressBar state, ProgressBar is empty all the time. I don't pass any arguments to start(Stage stage) in JavaFX, I don't know how to pass stage argument.

            Can you help me further?

            Thank you so much!


            • 3. Re: How Java call JavaFX?
              James_D

              "run file" and "run project" are NetBeans-specific, I think. I'm not a big NetBeans user: I primarily use Eclipse.

               

              A properly bundled JavaFX application will use a startup class for you: com.javafx.main.Main. It's main(...) method is actually the one that is called to start the application. As I understand it, that main(...) method checks to see if the JavaFX runtime is available and if so, calls Application.launch(...). If it's not available it has a fallback to notify the user and I think direct them to a download of a compatible JVM. It probably does some other stuff if launched from Java Web Start or from an applet.

              The Application.launch(...) method, in turn, starts the JavaFX application thread, creates a primary Stage, instantiates your application class, and then invokes start(...) on that instance and running on the JavaFX Application Thread, passing in the primary Stage that it created.

               

              So when you build a standard JavaFX application and create the jar file

               

              You shouldn't try to call start(...) directly yourself. One reason is that it must be executed on the JavaFX Application Thread, and depending on the context this can be difficult to ensure. Another reason is that you have to create a primary stage to call it, and it's not clear what, if any, special requirements there may be on that primary stage. You should be able to call Application.launch(...) and let it call start(...) for you. Note that if you do this yourself, you lose all the functionality (version checking, etc) provided by the com.javafx.main.Main startup class.

               

              So I would really try to avoid this scenario entirely: it's much better to use the in place framework and let the start(...) method be the entry point to your application. Why do you need to do this? Are you launching a JavaFX application from a Swing application?

               

              I don't know why your progress bar is not updating: that seems strange.

              • 4. Re: How Java call JavaFX?
                Liang123

                James_D,

                I post the current code here, you check it, you can find the exact situation.

                The whole project includes a few parts, I just do one of them, others hope to call my part from Java entry.

                Thank you so much!


                StartMenuFXML class: to load FXML

                package startmenufxml;

                 

                 

                import java.io.IOException;

                import java.util.logging.Level;

                import java.util.logging.Logger;

                import javafx.application.Application;

                import javafx.application.Platform;

                import javafx.fxml.FXMLLoader;

                import javafx.scene.Parent;

                import javafx.scene.Scene;

                import javafx.scene.control.Label;

                import javafx.scene.control.ProgressBar;

                import javafx.stage.Stage;

                 

                 

                /**

                *

                * @author

                * start interface to display a background image, current loading contents and

                * a progress bar

                */

                public class StartMenuFXML extends Application {

                    float outer=0;

                    Parent root;

                    Label startLabel;

                    ProgressBar progressBar;

                    Stage stage3;

                    Stage stage2;

                   

                    /*

                     * The second thread to handle current loading contents and

                     * a progress bar

                     */

                    class Progress extends Thread{

                    public Progress(Stage stage){

                        super();

                        stage3 =stage;

                    }

                   

                    @Override

                    public void run(){

                            outer=0.1f;

                            while(true){

                            Platform.runLater(new Runnable(){

                 

                 

                                @Override

                                public void run() {

                                        startLabel.setText("aaaa");

                                        startLabel.setVisible(true);

                                        progressBar.setProgress(outer);

                                        progressBar.setVisible(true);

                                }

                            });

                           

                            /*

                             * wait for 1000ms

                             */

                            try{

                                Progress.sleep(1000);

                            }catch(InterruptedException e){

                            }

                             outer=0.2f;

                             Platform.runLater(new Runnable(){

                 

                 

                                @Override

                                public void run() {

                                    startLabel.setText("bbbb");

                                        progressBar.setProgress(outer);

                                }

                               

                            });

                             /*

                             * wait for 2000ms

                             */

                             try{

                                Progress.sleep(2000);

                             }catch(InterruptedException e){

                             }

                             outer=0.4f;

                             Platform.runLater(new Runnable(){

                 

                 

                                @Override

                                public void run() {

                                    startLabel.setText("cccc");

                                        progressBar.setProgress(outer);

                                }

                               

                            });

                             /*

                             * wait for 2000ms

                             */

                             try{

                                Progress.sleep(2000);

                             }catch(InterruptedException e){

                             }

                             outer=0.6f;

                             Platform.runLater(new Runnable(){

                 

                 

                                @Override

                                public void run() {

                                        startLabel.setText("dddd");

                                        progressBar.setProgress(outer);

                //                    }

                                }

                               

                            });

                             /*

                             * wait for 2000ms

                             */

                             try{

                                Progress.sleep(2000);

                             }catch(InterruptedException e){

                                

                             }

                             outer=0.8f;

                             Platform.runLater(new Runnable(){

                 

                 

                                @Override

                                public void run() {

                                        startLabel.setText("eeee");

                                        progressBar.setProgress(outer);

                //                    }

                                }

                               

                            });

                             /*

                             * wait for 2000ms

                             */

                             try{

                                Progress.sleep(2000);

                             }catch(InterruptedException e){

                                

                             }

                             outer=1.0f;

                             if(outer>=0.999f){

                                 break;

                             }

                            }//while ends

                            Platform.runLater(new Runnable(){

                 

                 

                                @Override

                                public void run() {

                                    stage3.hide();

                                }

                               

                            });

                            /*

                             * automatically load login interface

                             */

                            Platform.runLater(new Runnable(){

                                @Override

                                public void run() {

                                    Stage stage2 = new Stage();

                                    Parent root2 = null;

                                try {

                                    root2 = FXMLLoader.load(getClass().getResource("LoginFXML.fxml"));

                                } catch (IOException ex) {

                                    Logger.getLogger(StartMenuFXML.class.getName()).log(Level.SEVERE, null, ex);

                                }

                                Scene scene2=new Scene(root2);

                                stage2.setTitle("Login Menu");

                                stage2.setScene(scene2);

                                stage2.show();

                                }

                            });

                    }//run() ends

                }//class Progress ends

                    @Override

                    public void start(final Stage stage) throws Exception {

                        Scene scene;

                        Progress p = new Progress(stage);

                       

                        root = FXMLLoader.load(getClass().getResource("StartMenuFXML.fxml"));

                        startLabel=(Label)root.lookup("#startLabel");

                        progressBar = (ProgressBar)root.lookup("#ProgressBar");

                        root.setStyle("-fx-background-image: url('erp2.jpg')");

                        scene=new Scene(root,600,400);

                        stage.setTitle("Start Progress");

                        p.start();

                        stage.setScene(scene);

                        stage.show();

                    }

                 

                 

                    /**

                     * The main() method is ignored in correctly deployed JavaFX application.

                     * main() serves only as fallback in case the application can not be

                     * launched through deployment artifacts, e.g., in IDEs with limited FX

                     * support. NetBeans ignores main().

                     *

                     * @param args the command line arguments

                     */

                    public static void main(String[] args) {

                        launch(args);

                    }

                }

                 

                ApplicationLoader class: want it to be entry of the project

                package startmenufxml;

                 

                 

                import java.io.InputStreamReader;

                import java.util.logging.Level;

                import java.util.logging.Logger;

                import javafx.application.Application;

                import javafx.stage.Stage;

                import javax.script.ScriptEngine;

                import javax.script.ScriptEngineManager;

                import javax.script.ScriptException;

                 

                 

                /**

                *

                * @author

                */

                public class ApplicationLoader {

                    public static void main(String[] args){

                        System.out.println("from main() method");

                        Application.launch(StartMenuFXML.class);

                    }

                }

                • 5. Re: How Java call JavaFX?
                  James_D

                  That's a bit of a mess and there's no way I'm going to debug it for you. You should consider:

                   

                  1. Using the Task class to manage tasks that are run away from the FX Application thread. You can use the progress property and updateProgress() method to correctly update the progress of the task. You are currently trying to access a field (outer) from multiple threads in a non-threadsafe way.

                  2. Use a controller class with injection to access Nodes defined in FXML. Using lookups like that is really dangerous: the lookups aren't guaranteed to work until the nodes have been rendered, so there's a good chance they'll be null when you try to access them. Even if it works in a development and test environment, there's no guarantee it'll work in production.

                   

                  It's still not clear to me why you want a customized launch to your application. You should design the application with the start() method as the entry point for the application. Divide it up from there, not before.

                  • 6. Re: How Java call JavaFX?
                    Liang123

                    James_D,

                    I tried Task class to manage tasks, the ProgressBar still does not refresh.

                    I am using a controller class with injection to access Nodes defined in FXML, I use lookup to use startLabel and progressBar.

                    The project requires a customized launch from Java.

                    Thank you very very much!

                    Best regards.