1

For some reason, my fx:id does not bind properly to my Controller class, and thus always causes an error.

Controller

package sample;

import javafx.fxml.FXML;

import java.awt.*;
import java.awt.event.ActionEvent;

public class Controller {

    @FXML public Button button;

    public void clickAction(ActionEvent actionEvent) {
        System.out.println("Button clicked.");
    }
}

FXML

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

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<BorderPane fx:controller="sample.Controller" 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">
   <Button text="Click me!" fx:id="button" onAction="#clickAction" BorderPane.alignment="CENTER"/>
</BorderPane>

I think I understand the source of my problem, but I do not understand how to properly address it. According an answer of this question, I think I am trying to assign FXML elements before the constructor is called (and these elements can only be assigned during/after initialisation).

Is there a way to do this without implementing Initializable? Or am I making a completely different mistake?

Community
  • 1
  • 1
haz
  • 2,034
  • 4
  • 28
  • 52

4 Answers4

3

You use the imports

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

in your fxml file.

Therefore the Button instance created while loading the fxml file is a javafx.scene.control.Button.

The type of the field this is injected to needs be something a javafx.scene.control.Button can be assigned to.

Since your only imports in the controller besides javafx.fxml.FXML are from the java.awt packages, this is clearly not the case for the button field (type java.awt.Button).

Fix your controller to import the required classes from the javafx packages instead:

import javafx.fxml.FXML;

import javafx.scene.control.Button;
import javafx.event.ActionEvent;

BTW: You can also leave out the parameter of the onAction handler, if you do not use it:

public void clickAction() {
    System.out.println("Button clicked.");
}
fabian
  • 80,457
  • 12
  • 86
  • 114
  • Fantastic. I guess I just hit enter without thinking when Intellij suggested my imports. Thanks! – haz Sep 18 '16 at 12:14
3

Note that:

1)You were using the old Swing library in the import statements

2)You need to add @FXML on every method and element with id defined using fxml

Your code should be:

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.event.ActionEvent;

public class Controller {

    @FXML
     public Button button;

     @FXML
    public void clickAction(ActionEvent actionEvent) {
        System.out.println("Button clicked.");
    }
}

Also mention that as Fabian and Michael said on their answers you don't need ActionEvent actionEvent into the clickAction method.So finnally:

 @FXML
        public void clickAction() {
            System.out.println("Button clicked.");
        }
GOXR3PLUS
  • 6,877
  • 9
  • 44
  • 93
1

The only problem I see if your import of ActionEvent. You are using awt and should be using javafx ActionEvent.

import javafx.event.ActionEvent

Edit 1

You also dont need to have ActionEvent as a parameter if you dont need it, just an FYI.

Hypnic Jerk
  • 1,192
  • 3
  • 14
  • 32
0

Recently, I think I had a similar problem. FXML was giving me error. The reason was an incorrectly imported library. Instead java.scene.control , I imported java.awt .

look at the possibilities:

enter image description here

Smyhail
  • 99
  • 7