No injectable field found in FXML Controller class

rzaaeeff picture rzaaeeff · Nov 11, 2014 · Viewed 30.3k times · Source

It's about JavaFX. When i want to inject fx:id in Scene Builder, i get this warning:
No injectable field found in FXML Controller class for the id 'something'.
I wanted to ignore it, and created a function, but it didn't work either. I created mainController class and added it into my FXML file. Here are my codes...

mainController.java

package main;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.Slider;

public class mainController implements Initializable {

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // TODO Auto-generated method stub
    }

    @FXML
    private ProgressBar pb;
    @FXML
    private Slider sl;
        @FXML
        private Label label;

    public void changed(ActionEvent event){

        }
}


Main.java

package main;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("/fxml/main.fxml"));
        Scene scene = new Scene(root, 600, 400);
        scene.getStylesheets().add("/fxml/styles/main.css");

        ProgressBar pb1 = new ProgressBar();
        ProgressBar pb2 = new ProgressBar();

        //pb1.

        //primaryStage.setResizable(false);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Something");
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}


main.fxml

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

<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>


<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="main.mainController">
   <children>
      <BorderPane layoutX="14.0" layoutY="14.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <top>
            <ProgressBar fx:id="pb" prefWidth="200.0" progress="0.0" BorderPane.alignment="CENTER">
               <BorderPane.margin>
                  <Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
               </BorderPane.margin>
            </ProgressBar>
         </top>
         <bottom>
            <Slider fx:id="sl" onDragDetected="#changed" BorderPane.alignment="CENTER">
               <BorderPane.margin>
                  <Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
               </BorderPane.margin>
            </Slider>
         </bottom>
      </BorderPane>
   </children>
</AnchorPane>

I did same things in my old projects, and they work like a charm. But this one seems not to obey me. Thanks in advance...

Answer

Jos&#233; Pereda picture José Pereda · Nov 11, 2014

In Scene Builder, if the FXML file is associated to a controller class, you know that what makes the connection between the variable in the controller class (pb) and the object in the FXML file (<ProgressBar ... />) is the value of the object's fx:id.

So when you set an fx:id on an object, Scene Builder tries to parse the controller class trying to find a variable of that name.

If it doesn't find any, it displays this warning. It's just a reminder that you may want to add such a variable to the controller class, or that you have to choose other valid name from a list.

Since you have label defined on your controller, if you try to add a Label on Scene Builder, you can get its fx:id from the list:

Scene Builder

But if you assing another name, you will get the warning:

Scene Builder warning

On a side note, you don't need to instantiate the progress bar on the main class, since it will be instantiated in the controller. And ìf you try to link change(ActionEvent event) to a method in Scene Builder (#change), you have to annotate it with @FXML. Anyway, don't use onDragDetected with the slider.