20

I have an FXML file that has buttons with onMouseClicked attributes. I do not set a Controller up in the FXML because I have constructor injected data I want to provide to the Controller.

  <Button mnemonicParsing="false" onMouseClicked="#newWidgetRequestButtonClicked" text="New Widget..." />

I'm setting the Controller programatically, and my controller contains the methods specified in the FXML. The Controller functions execute, and everything works fine.

FXMLLoader loader = new FXMLLoader(getClass().getResource("MainView.fxml"));
MyController controller = new MyController(...);
loader.setController(controller);

My problem lies in IntelliJ's inspection of the .fxml files. On each occurrence of the function reference, it reports "Error:(45, 54) No controller specified for top level element". I am looking at IntelliJ's inspection rules and do not see this rule in the JavaFX section. Again, the program builds and runs just fine, so it is not a real compilation error. I want to disable this error notification.

How can I avoid this error?

Stealth Rabbi
  • 10,156
  • 22
  • 100
  • 176

4 Answers4

6

You need to add top level element fx:controller.

Lets say you have a basic fxml file with a just anchor pane with a button like the fxml below.

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

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


<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">
   <children>
      <Button layoutX="102.0" layoutY="50.0" mnemonicParsing="false" text="Button" />
   </children>
</AnchorPane>

Your top level element will be the anchor pane in this case. If you want to use action buttons like onMouseClicked you need to tell to fxml you controller class in your top level element (in this case anchor pane) like below.

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

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


<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="com.example.Controller">
   <children>
      <Button fx:id="buttonExample"  layoutX="102.0" layoutY="50.0" mnemonicParsing="false" text="Button" />
   </children>
</AnchorPane>

fx:controller="com.example.Controller" line says that my control class is Controller which is in the com.example package.

Also your elements id's should begin with fx like in the example (fx:id="buttonExample").

emin deniz
  • 439
  • 5
  • 13
  • 2
    if you specificy that controlller, then when you try to reach textfields,buttons in your controller class you will get nullpointer exception. – Mert Serimer Sep 19 '17 at 11:51
  • 8
    OP said: " I do not set a Controller up in the FXML because I have constructor injected data I want to provide to the Controller." – Jean-François Côté Mar 12 '18 at 17:14
5

Even, I don't like those notifications. I set the controllers programatically. To disable it, you need to set the highlighting level to none. To do this, open your fxml file and at the very bottom on the right side, you will see a hector icon. Click on the hector icon and set the highlight level to none by dragging the slider.

You will need to restart the IDE for the changes to take effect. The highlighting will be set to none for that file only. Other files won't see any change in their highlighting behavior until we set their highlighting level to none again.

Use the following link, if you were unable to find hector icon. https://www.jetbrains.com/help/idea/status-bar.html

lambad
  • 1,046
  • 10
  • 21
3

It is nice task to find out the work-around for this issue. The IntelliJ is able to follow the reference via attribute fx:controller="your.package.here.MyController". The defined parameters should be passed the controller new MyController(...);. This is the specified task.

So, how about integrate JavaFX and CDI? Instead of annotating the attributes, you can add the @Inject annotation on a constructor.

In this way you can create an instance of the controller with specified parameters and set the reference using the fx:controller attribute.

https://github.com/rusty85/javafx-cdi-demo

  • Is there a link for that work around? And what do you mean "com.example"? Is that suppose to be replaced by the project's package? – JΛYDΞV Dec 26 '21 at 07:25
  • I mean "your.package.name.MyController". The possible integration example you can find here: https://dzone.com/articles/fxml-javafx-powered-cdi-jboss and here you will find the information to constructor inject: https://www.baeldung.com/java-ee-cdi – The 5th column mouse Dec 26 '21 at 10:35
  • @JΛY-ÐΞV I get the work around running locally on my environment. So if you need help let me know. – The 5th column mouse Dec 26 '21 at 18:47
  • Okay, I had to go back to an old project writing a JSON parser written in C++ & implemented in a Native Node.js module, so I am not working with JFX/OpenFX for at least a month, maybe two. I have to come back to the FX project though, as I have it sold to a client already, and perhaps you will still be around? If you are I would certainly love to get some clarity from you. I would like to try implementing the project using CDI. Anyhow, meanwhile I have to do somthing w/ the bounty so it's yours. – JΛYDΞV Dec 27 '21 at 11:10
  • I appreciate you taking the time to make these comments! – JΛYDΞV Dec 27 '21 at 11:10
  • BTW, what is the 5th column mouse? – JΛYDΞV Dec 27 '21 at 11:11
  • Thank you, but I would like to know if the solution works for you. Here is the minimal implementation: https://github.com/rusty85/javafx-cdi-demo – The 5th column mouse Dec 27 '21 at 11:14
  • 5th column mouse is very old american cartoon but exact translated in russian it would mean underdog mouse) – The 5th column mouse Dec 27 '21 at 11:22
  • Oh okay, because I am an American, I actually know exactly what you're talking about. I loved all those old cartoons. I really liked Mighty Mouse, and Wiley Coyote. Anyway, good pick for a name. – JΛYDΞV Dec 27 '21 at 15:42
0

I had absolutely same error in identical use case. Solution was stupidly easy: each method, what is assigned with the callbacks in the fxml file, should be annotated in the controller with @FXML tag.

Even if it's method not yet implemented So

<Button mnemonicParsing="false" onMouseClicked="#newWidgetRequestButtonClicked" text="New Widget..." />

Requires also according method defined in the controller class:

@FXML
void newWidgetRequestButtonClicked() {}
Leonid-98
  • 71
  • 6