6

I already searched the deepest depths of the interweb but no answer will seem to be found -.-

The problem is in my javaFx programm i want to write. But i can't make it any further than adding the controller class. I followed nearly every tutorial a could find, but the issue still remains unknown to me.

This is the exception:

javafx.fxml.LoadException: 
/U:/BankingSolutions/MediaCenterFX/bin/main/ressources/view/MainUI.fxml:12

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2617)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:104)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:976)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:216)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:738)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2723)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3230)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3191)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3164)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3140)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3120)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3113)
at application.Main.start(Main.java:15)
at com.sun.javafx.application.LauncherImpl$8.run(LauncherImpl.java:837)
at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:335)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:301)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:298)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:298)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: /java/controllers/MainUIController
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:925)
... 24 more

and this is the code. there are thre classes: The Main.class, my MainUI.fxml which i created using scenebuilder 2 and my MainUIController.class which should obviously work as the mainuis controller

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;


public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        try {
            AnchorPane root = (AnchorPane) FXMLLoader.load(getClass().getResource("/main/ressources/view/MainUI.fxml"));
            Scene scene = new Scene(root);
            primaryStage.setScene(scene);
            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

_______________________________________________

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

<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="root" prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="/java/controllers/MainUIController">
   <children>
      <BorderPane fx:id="borderPane01" layoutX="657.0" layoutY="304.0" prefHeight="336.0" prefWidth="403.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <bottom>
            <AnchorPane fx:id="bp_bottom" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
         </bottom>
         <left>
            <GridPane fx:id="bp_left_grid" prefHeight="680.0" prefWidth="238.0" BorderPane.alignment="CENTER">
              <columnConstraints>
                  <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
              </columnConstraints>
              <rowConstraints>
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
              </rowConstraints>
               <children>
                  <Button fx:id="btn_search" mnemonicParsing="false" prefHeight="48.0" prefWidth="172.0" text="Suche" GridPane.columnSpan="2147483647" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER">
                     <GridPane.margin>
                        <Insets />
                     </GridPane.margin>
                     <font>
                        <Font size="24.0" />
                     </font>
                  </Button>
                  <Button fx:id="btn_series" mnemonicParsing="false" prefHeight="48.0" prefWidth="172.0" text="Serien" wrapText="true" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
                     <font>
                        <Font size="24.0" />
                     </font>
                  </Button>
                  <Button fx:id="btn_download" mnemonicParsing="false" prefHeight="48.0" prefWidth="172.0" text="Download" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER">
                     <font>
                        <Font size="24.0" />
                     </font>
                  </Button>
                  <Button fx:id="btn_movies" mnemonicParsing="false" prefHeight="48.0" prefWidth="172.0" text="Filme" wrapText="true" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER">
                     <font>
                        <Font size="24.0" />
                     </font>
                  </Button>
                  <Button fx:id="btn_exit" mnemonicParsing="false" prefHeight="48.0" prefWidth="172.0" text="Beenden" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="6" GridPane.valignment="CENTER">
                     <font>
                        <Font size="24.0" />
                     </font>
                  </Button>
                  <Button fx:id="btn_settings" mnemonicParsing="false" prefHeight="48.0" prefWidth="172.0" text="Optionen" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="4" GridPane.valignment="CENTER">
                     <font>
                        <Font size="24.0" />
                     </font>
                  </Button>
                  <Button fx:id="btn_dashboard" mnemonicParsing="false" prefHeight="48.0" prefWidth="172.0" text="Dashboard" GridPane.columnSpan="3" GridPane.halignment="CENTER" GridPane.rowIndex="5" GridPane.valignment="CENTER">
                     <font>
                        <Font size="24.0" />
                     </font>
                  </Button>

               </children>
            </GridPane>
         </left>
         <top>
            <AnchorPane fx:id="bp_top" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
               <children>
                  <Label fx:id="headlabel" alignment="CENTER" layoutX="737.0" layoutY="92.0" prefHeight="200.0" prefWidth="1920.0" text="Dashboard" textAlignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                     <font>
                        <Font size="48.0" />
                     </font>
                  </Label>
               </children>
            </AnchorPane>
         </top>
         <center>
            <AnchorPane fx:id="bp_center" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
         </center>
         <right>
            <AnchorPane fx:id="bp_right" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
         </right>
      </BorderPane>
   </children>
</AnchorPane>

______________________________________________

package main.java.controllers;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;

public class MainUIController{

    @FXML // ResourceBundle that was given to the FXMLLoader
    private ResourceBundle resources;

    @FXML // URL location of the FXML file that was given to the FXMLLoader
    private URL location;

    @FXML // fx:id="btn_search"
    private Button btn_search; // Value injected by FXMLLoader

    @FXML // fx:id="btn_movies"
    private Button btn_movies; // Value injected by FXMLLoader

    @FXML // fx:id="btn_exit"
    private Button btn_exit; // Value injected by FXMLLoader

    @FXML // fx:id="btn_series"
    private Button btn_series; // Value injected by FXMLLoader

    @FXML // fx:id="bp_right"
    private AnchorPane bp_right; // Value injected by FXMLLoader

    @FXML // fx:id="bp_bottom"
    private AnchorPane bp_bottom; // Value injected by FXMLLoader

    @FXML // fx:id="borderPane01"
    private BorderPane borderPane01; // Value injected by FXMLLoader

    @FXML // fx:id="headlabel"
    private Label headlabel; // Value injected by FXMLLoader

    @FXML // fx:id="bp_left_grid"
    private GridPane bp_left_grid; // Value injected by FXMLLoader

    @FXML // fx:id="bp_top"
    private AnchorPane bp_top; // Value injected by FXMLLoader

    @FXML // fx:id="root"
    private AnchorPane root; // Value injected by FXMLLoader

    @FXML // fx:id="btn_download"
    private Button btn_download; // Value injected by FXMLLoader

    @FXML // fx:id="btn_dashboard
    private Button btn_dashboard; // Value injected by FXMLLoader

    @FXML // fx:id="bp_center"
    private AnchorPane bp_center; // Value injected by FXMLLoader

    @FXML // fx:id="btn_settings"
    private Button btn_settings; // Value injected by FXMLLoader

    @FXML // This method is called by the FXMLLoader when initialization is complete
    void initialize() {
        assert root         != null : "fx:id=\"root\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert borderPane01 != null : "fx:id=\"borderPane01\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert bp_top       != null : "fx:id=\"bp_top\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert headlabel    != null : "fx:id=\"headlabel\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert bp_left_grid != null : "fx:id=\"bp_left_grid\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert bp_center    != null : "fx:id=\"bp_center\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert bp_right     != null : "fx:id=\"bp_right\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert bp_bottom    != null : "fx:id=\"bp_bottom\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert btn_search   != null : "fx:id=\"btn_search\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert btn_series   != null : "fx:id=\"btn_series\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert btn_movies   != null : "fx:id=\"btn_movies\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert btn_download != null : "fx:id=\"btn_download\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert btn_settings != null : "fx:id=\"btn_settings\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert btn_dashboard!= null : "fx:id=\"dashboard\" was not injected: check your FXML file 'MainUI.fxml'.";
        assert btn_exit     != null : "fx:id=\"btn_exit\" was not injected: check your FXML file 'MainUI.fxml'.";

        btn_search.setOnAction(value -> {
            System.out.println("Search pressed"); //TODO
        });
        btn_series.setOnAction(value ->{
            System.out.println("series pressed");
        });
        btn_movies.setOnAction(value ->{
            System.out.println("movies pressed");
        });
        btn_download.setOnAction(value ->{
            System.out.println("download pressed");
        });
        btn_settings.setOnAction(value ->{
            System.out.println("settings pressed");
        });
        btn_dashboard.setOnAction(value ->{
            System.out.println("dashboard pressed");
        });
        btn_exit.setOnAction(value ->{
            System.out.println("exit pressed");
        });


    }
}

Edit: Here is my package structure:

src
|-application
    |here is my main application
|-main
    |-java
        |-controllers
            |here are my controllers
        |-dao
        |-service
    |-ressources
        |-css
        |-images
        |-view
           |here are the fxml files
PooBucket
  • 63
  • 1
  • 1
  • 7
  • Considering `main/resources` is just the path to your classpath, have you tried replacing `getClass().getResource("/main/ressources/view/MainUI.fxml")` with `getClass().getResource("/view/MainUI.fxml")`? – ItachiUchiha Jun 30 '15 at 10:17
  • Can you add the code for the fxml as well. I am of the opinion that you have incorrect for the controller in your fmxl as well. – ItachiUchiha Jun 30 '15 at 10:24
  • Not sure, but I guess the package of the `MainUIController` is wrong. `Caused by: java.lang.ClassNotFoundException: /java/controllers/MainUIController` says the class is in package `java.controllers` but the class itself defines the package as: `package main.java.controllers;` – MalaKa Jun 30 '15 at 10:25
  • @ItachiUchiha Yeah i already tried that :/ – PooBucket Jun 30 '15 at 11:12
  • @Malaka I edited my post and added my package structure to it. What would you suggest? – PooBucket Jun 30 '15 at 11:13

2 Answers2

3

The fx:controller attribute is expecting the fully qualified classname of the controller class. I.e. assuming you have

package main.java.controllers ;

public class MainUIController { ... }

you should have

fx:controller="main.java.controllers.MainUIController"
James_D
  • 201,275
  • 16
  • 291
  • 322
  • I already tried that out, but thank you. :/ but it doesn't semm to change anything – PooBucket Jun 30 '15 at 11:15
  • If you read the stack trace, it is clear that the `fx:controller` is the problem. I updated the answer slightly after reading your comments above. – James_D Jun 30 '15 at 11:17
  • 1
    whoa sorry dude, i tried your answer again and improved it with Malakas suggestion of package architecture and now it works just fine!! Awesome :) – PooBucket Jun 30 '15 at 11:50
1

I suggest to change the project structure. The resources should not be resided in the sources itself. So my suggestion is the following project structure:

src
|-main
    |-java <-- This should be your 'sources root'
        |-application <-- The application itself is within the new sources root
        |-controllers
            |here are my controllers
        |-dao
        |-service
    |-resources <-- all resources (css files, images, fxml files) should be with a subfolder of the resources. This folder should be marked as 'resources root'
        |-css
        |-images
        |-view
            |here are the fxml files

This structure can be set up in any IDE. How you can set it up depends on the IDE itself. Normally you can simply right-click the folder in the overview and mark is as sources/resources root. The exact names for 'source root' and 'resources root' depend on the IDE.

The Main is now in the package application and the MainUIController is in the package controllers.

In the FXML-File you should specify:

fx:controller="controllers.MainUIController"

Loading the FXML-File should work with:

AnchorPane root = (AnchorPane) FXMLLoader.load(getClass().getClassLoader().getResource("view/MainUI.fxml"));

As a reference for the following explanation, have a look here:
The ClassLoader always starts at the root of your resources. If you only use getClass, the path to the resource is a relative path. After dealing with it several times, I for myself have decided to always use absolute paths and therefore use the getClassLoader.
As explained in the link above, please note that

getClass().getClassLoader().getResource("view/MainUI.fxml");

could be replaced by

getClass().getResource("view/MainUI.fxml");

I think that I somewhere read, that it is better to directly use the InputStream if available, as dealing with URLs within JAR-Files can be tricky sometimes (but I currently can't find a reference to support that). So as an alternative to the getResource(..), you could use:

FXMLLoader loader = new FXMLLoader();
Parent root = loader.load(getClass().getClassLoader().getResourceAsStream("view/MainUI.fxml");
Community
  • 1
  • 1
MalaKa
  • 3,734
  • 2
  • 18
  • 31
  • Yeah, thank you. Had it like that except for the application folder to be inside the java folder. The textbox must have messed around with my spacings – PooBucket Jun 30 '15 at 11:40
  • You can generate a layout as MalaKa suggests by using a [JavaFX Maven archetype](https://github.com/javafx-maven-plugin/javafx-basic-archetype) (though it may confuse you more than help if you have no familiarity with Maven). – jewelsea Jun 30 '15 at 11:47
  • Mhmm.. the getClassLoader() - appears to be unknown.. do i miss any imports here or something? – PooBucket Jun 30 '15 at 11:48
  • @PooBucket Yes, I'm sorry. Please see the updated line, that should work. – MalaKa Jun 30 '15 at 11:50
  • Thank you, i rearranged the package structure, by placing the application folder within the java package and overworked the used paths and now it runs great! Thank you for awesome support! – PooBucket Jun 30 '15 at 11:51
  • Thank you, also works for me. But even though my problem is solved, i am still curious about what the difference between FXMLLoader.load(getClass().getResource(... and FXMLLoader.load(getClass().getClassLoader().getResourceAsStream(... is o.O – PooBucket Jun 30 '15 at 11:54
  • You're welcome. I've also added some more explanation. – MalaKa Jun 30 '15 at 12:09
  • A lot of your explanation seems incorrect to me. `getClass().getResource()` and `getClass().getClassLoader().getResource()` do the exact same thing: see [Javadocs](http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getResource-java.lang.String-): `getClass().getResource()` delegates to the call on the class loader. The difference between `FXMLLoader.load(URL)` and `FXMLLoader.load(InputStream)` is that the first is a `static` method while the second is an instance method (so your code `FXMLLoader.load(getClass().getClassLoader().getResourceAsStream(...))` won't even compile). – James_D Jun 30 '15 at 12:44
  • @James_D Thank you, you are absolutely right about the `FXMLLoader`. I've also changed the line and the explanation of `getClass()` vs `getClass().getClassLoader()` for clearification. – MalaKa Jun 30 '15 at 13:24
  • 1
    As one more note on the `FXMLLoader`, if you use the `load(InputStream)` method you will lose any location-based information: i.e. [Location Resolution](http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html#location_resolution) will not work in your FXML. If you have an FXML resource (file, etc) then you should use a URL-based load; imo you should only use the InputStream load in the rare case you are generating a stream "on the fly" (i.e. there is no resource). I prefer `FXMLLoader l = new FXMLLoader(URL); Parent root = l.load();` – James_D Jun 30 '15 at 13:44