6

I am attempting to load the main screen for my application, which in fact never actually runs and shows a screen. Upon further investigation (running it through the NetBeans debugger), I found that my code never executes after FXMLLoader.load(url); -- it stops there, and does not throw any error. I do know that the url is correct- I checked the value of it, and it is correct. Anyone know how to fix it? Thanks in advance!


<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.text.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-      Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8"    xmlns:fx="http://javafx.com/fxml/1" fx:controller="graphics.MainScreenController">
<children>
<Text fx:id="funds" layoutX="489.0" layoutY="383.0" strokeType="OUTSIDE" strokeWidth="0.0" text="USD 52,356,000.07">
</Text>
</children></AnchorPane>

package graphics;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 * FXML Controller class
 *
 */
 public class MainScreenController extends Application implements Initializable {


@FXML
private Text funds;

/**
 * Initializes the controller class.
 */
public void initialize(URL url, ResourceBundle rb) {  
    start(new Stage());

}    

@Override
public void start(Stage primaryStage){
    Parent root = null;
    try {
        URL url = getClass().getResource("MainScreen.fxml");
        root = FXMLLoader.load(url);
    } catch (Exception ex) {
        Logger.getLogger(MainScreenController.class.getName()).log(Level.SEVERE, null, ex);
    }
    Scene scene = new Scene(root,1200,800);
    primaryStage.setTitle("Title");
    primaryStage.setScene(scene);
    primaryStage.show();
}

}
erzr2
  • 155
  • 3
  • 12
  • What is in "MainScreen.fxml"? Try with simple layout, is it being loaded? – Uluk Biy Jun 13 '14 at 17:43
  • MainScreen.fxml is 5 rectangles, and a couple of buttons on a screen. It is not being loaded, but no error is thrown. – erzr2 Jun 13 '14 at 19:33
  • Leave only simple a Label control and delete all other controls from MainScreen. Does th problem persist? – Uluk Biy Jun 13 '14 at 20:01
  • Yes it does persist. Simplified it down to a single Text object with no formatting. – erzr2 Jun 13 '14 at 20:05
  • Did you try to change the exception from IOException to Exception maybe this shows something? – Inge Jun 14 '14 at 06:37
  • Gives me java.lang.StackOverflowError, java.lang.reflect.InvocationTargetException, but only after a long while. – erzr2 Jun 14 '14 at 17:29
  • It is possible that the controller (perhaps initialize()) for your FXML is getting called and not returning. Try putting some diagnostic messages in your controller and see if they are being called (or not). – Kolban Jun 14 '14 at 22:38
  • What does your graphics.MainScreenController look like? – Inge Jun 15 '14 at 07:54
  • Posted the MainScreenController class, also it seems initialize is not running. – erzr2 Jun 16 '14 at 13:35

5 Answers5

5

You have created an infinite loop with the initialize() method. The initialize method is automatically called by the FXMLLoader.

You are calling start() from the initialize() method which loads the MainScreen.fxml file which creates a new MainScreenController instance. The FXMLLoader automatically calls initialize() on the new instance which in turn calls start() which loads MainScreen.xml again and so on forever.

Since JavaFX 2.2 the Initializable interface is no longer the preferred way to initialize controllers after the FXML has been loaded. This was changed to use the @FXML annotation instead. The question What is "automatic injection of location and resources properties into the controller" in JavaFX? shows an example of the new method.

Also, I'm not sure why you are creating a new Stage() in your initialize() method. Normally to get the Stage you need to call launch() on the Application and the start() method will be automatically called with the Stage for you. An example is here: http://docs.oracle.com/javafx/2/get_started/hello_world.htm

Community
  • 1
  • 1
Aaron
  • 5,931
  • 4
  • 27
  • 31
1

This is not conventional JavaFX code.

You should use main and static launch methods to invoke your aplication

Example:

public static void main(String[] args) {
        launch(args);
    }

And launch invokes start method.

Please check http://docs.oracle.com/javafx/2/get_started/hello_world.htm to create

I dont know why you use that kind of method to attach main content to screen

Or I don't understand problem.

1

This is not conventional JavafX code.

You should use main and static launch methods to invoke your application

Example:

 public static void main(String[] args) {
        launch(args);
    }

And launch invokes start method.

Please check http://docs.oracle.com/javafx/2/get_started/hello_world.htm for your reference.

Rahul Patel
  • 87
  • 1
  • 11
0

I have seen these issues too. The cause or causes can vary. I have been compiling a hit-list of things to check, try, comment-out, etc. From a TDD perspective I recommend adding unit test to load every FXML file with a property bundle and style sheets as needed. The test should also check each controller for the injected '@FXML' variables.

Specifically you have an infinite loop, as Aaron says, because:

  • primaryStage.show();

Will call:

  • initialize( URL url, ResourceBundle rb)

JavaFX runtime wil be very confused by then. I suggest you use one of Netbeans: "JavaFX Application" templates (following). The JavaFX run-time will call your start() method. Put launch() in your main() method.

Netbeans:

  • File /
    • New Project /
      • Maven ... (my preference)
        • JavaFX Application
      • JavaFX ...
        • JavaFX Application

These days I have a bare-bones project "Maven :: JavaFX Application" project called Simple. It does nothing but load a given FXML file. I use that to test any FXML problem in a 'known' environment.

After the Start() method has called LoadFXML( ... ), your controller will be loaded and initialize( ) method is called when you see the controller specification:

  • fx:controller="graphics.MainScreenController"

From the code in your question there are some things not said that you can check if you have further trouble:

  • Ensure the FXML file name is exactly the same case in the URL, case sensitive: "MainScreen.fxml"
  • Any fx:id="componentName" assignments in the FXML will expect an '@FXML' injection in the (code-behind) controller. You probably wont see an error for this either, just throw a NullPointerException. That's one of the most frustrating errors because everything looks OK.
  • The opposite is also true. If you have an '@FXML' injection in the (code-behind) controller but no corresponding fx:id in the FXML, things can get confused too.
    • On this one watchout Scene Builder. At some point it named my fx:id="myList" to fx:id="myList1", probably from a cut-n-paste. Hard to find too.

Some times you just need to check-everything. You can check the things listed the 'FXML diagnostic ...' question linked below.

This problem is indirect recursion. Use one of the Netbeans JavaFX templates. I prefer the Maven layout because it makes a nice structure with FXML, CSS, etc. files and test folders.

Add some diagnostics in the JavaFX code: try/catch, logging, ... Most of the JavaFX examples I've seen show shiny features, with less emphasis on robustness. Also when using FXML be aware that even after your Java code has been compiles and shipped, someone can change the FXML, CSS and other resources with NO recompile.

Powerful tools like JavaFX comes with responsibilities . . .

Community
  • 1
  • 1
will
  • 4,799
  • 8
  • 54
  • 90
0

A possibility for getting stuck on the load method call is that an exception is being thrown which is being swallowed.

Check for different exceptions, particularly NullPointerException.

demongolem
  • 9,474
  • 36
  • 90
  • 105