Search code examples
javajavafxfxmlfxmlloader

I need help to fix a program in java fx that gives me exceptions


Javafx problem that doesn't find the fxml file even if they are in the same package. I really can't find any errors in the code and so your comments are more than welcome and SceneBuilder now doesn't allow me to open the fxml file because it says that the fx:controller can only be applied to root element, but i already put the fx controller in the root element .

Main Class

package application;

import javafx.application.Application;
import javafx.stage.Stage; 
import javafx.scene.Parent; 
import javafx.scene.Scene;
import javafx.scene.control.Alert; 
import javafx.scene.control.Alert.AlertType; 
import javafx.fxml.FXMLLoader;

public class LoginRegistrazioneDB  extends Application { 
@Override public void start(Stage primaryStage) throws Exception{
    FXMLLoader loader = new FXMLLoader(getClass().getResource("LoginRegFxml.fxml"));
    Parent root  = loader.load();
    Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.show();
}

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

Fxml file named LoginRegFxml.fxml

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




<VBox fx:controller="LoginRegistrazioneDB/LoginRegFxmlController"
    xmlns:fx="http://javafx.com/fxml">
<AnchorPane fx:controller="LoginRegistrazioneDB/LoginRegFxmlController" id="AnchorPane" prefHeight="699.0" prefWidth="1061.0" style="-fx-background-color: black;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.LoginRegFxmlController">
   <children>
      <Accordion expandedPane="$tpReg" layoutX="52.0" layoutY="148.0" prefHeight="504.0" prefWidth="938.0">
        <panes>
          <TitledPane fx:id="tpReg" animated="false" text="Registrazione">
            <content>
              <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                     <children>
                        <TextField fx:id="usernameReg" layoutX="497.0" layoutY="60.0" prefHeight="31.0" prefWidth="285.0" />
                        <TextField fx:id="emailReg" layoutX="497.0" layoutY="119.0" prefHeight="31.0" prefWidth="286.0" />
                        <PasswordField fx:id="passwordReg" layoutX="498.0" layoutY="181.0" prefHeight="31.0" prefWidth="286.0" />
                        <DatePicker fx:id="date" layoutX="498.0" layoutY="239.0" prefHeight="31.0" prefWidth="287.0" />
                        <Label layoutX="38.0" layoutY="55.0" prefHeight="41.0" prefWidth="199.0" text="Username">
                           <font>
                              <Font name="Yu Gothic Light" size="26.0" />
                           </font>
                        </Label>
                        <Label layoutX="38.0" layoutY="177.0" prefHeight="40.0" prefWidth="121.0" text="Password">
                           <font>
                              <Font name="Yu Gothic Light" size="26.0" />
                           </font>
                        </Label>
                        <Label layoutX="38.0" layoutY="232.0" prefHeight="46.0" prefWidth="182.0" text="Data di Nascita">
                           <font>
                              <Font name="Yu Gothic Light" size="26.0" />
                           </font>
                        </Label>
                        <Label layoutX="38.0" layoutY="119.0" prefHeight="31.0" prefWidth="84.0" text="Email">
                           <font>
                              <Font name="Yu Gothic Light" size="26.0" />
                           </font>
                        </Label>
                        
                        <Button fx:id="buttonReg"  layoutX="782.0" layoutY="353.0" mnemonicParsing="false" onAction="#handleButtonClick" style="-fx-background-color: purple;" text="Registrazione" textFill="WHITE" />
                        <ProgressIndicator fx:id="progressReg" layoutX="723.0" layoutY="343.0" progress="0.0" />
                     </children>
                  </AnchorPane>
            </content>
          </TitledPane>
          <TitledPane animated="false" text="Login">
            <content>
              <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                     <children>
                        <Label layoutX="47.0" layoutY="80.0" prefHeight="58.0" prefWidth="159.0" text="Username ">
                           <font>
                              <Font name="Yu Gothic Light" size="30.0" />
                           </font>
                        </Label>
                        <Label layoutX="47.0" layoutY="169.0" prefHeight="52.0" prefWidth="140.0" text="Password">
                           <font>
                              <Font name="Yu Gothic Light" size="30.0" />
                           </font>
                        </Label>
                        <PasswordField fx:id="passwordLog" layoutX="368.0" layoutY="180.0" prefHeight="31.0" prefWidth="465.0" />
                        <TextField fx:id="usernameLog" layoutX="368.0" layoutY="94.0" prefHeight="31.0" prefWidth="465.0" />
                        <Button fx:id="buttonLog" onAction="#handleButtonClickLog" layoutX="775.0" layoutY="304.0" mnemonicParsing="false" prefHeight="56.0" prefWidth="116.0" style="-fx-background-color: purple;" text="Login" textFill="WHITE" />
                        <ProgressIndicator fx:id="progressLog" layoutX="713.0" layoutY="303.0" prefHeight="58.0" prefWidth="36.0" progress="0.0" />
                     </children>
                  </AnchorPane>
            </content>
          </TitledPane>
        </panes>
      </Accordion>
      <Text fx:id="textPrin" fill="WHITE" layoutX="52.0" layoutY="61.0" strokeType="OUTSIDE" strokeWidth="0.0" text="DC PROGRAMS" wrappingWidth="236.90087890625">
         <font>
            <Font name="PMingLiU-ExtB" size="42.0" />
         </font>
      </Text>
   </children>
</AnchorPane>

</VBox>

Controller

package application;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;

import javafx.event.*;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.text.*;
import javafx.stage.*;
import javafx.scene.*;

public class LoginRegFxmlController {

    
    
    @FXML
    private TitledPane tpReg;

    @FXML
    private Text textPrin;
    
    //Registration
    @FXML
    private TextField usernameReg;
    
    @FXML
    private TextField emailReg;
    
    @FXML
    private PasswordField passwordReg;
    
    @FXML
    private DatePicker date; 

    @FXML
    private ProgressIndicator progressReg;
    
    @FXML
    public Button buttonReg;
    
    public void handleButtonClick(ActionEvent event) {
        
        //perchè non funziona la funzione gettext su username
        String u = usernameReg.getText();
        
        String e = emailReg.getText();
        //algo per password 
        
        String p = passwordReg.getText();
        LocalDate dataIns = date.getValue();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String d = dataIns.format(formatter);
        
         String url = "jdbc:mysql://localhost/utentiapp?serverTimezone=Europe/Rome";
         String user = "root";
         String pass = "";
         
         try {
             Connection conn = DriverManager.getConnection(url, user, pass);
             Statement s = conn.createStatement();
      
             String checkQ = "SELECT USERNAME, EMAIL FROM UTENTI "
                    + " WHERE USERNAME = '"+u+"' ";
             ResultSet st = s.executeQuery(checkQ);
             int f=0;
             do {
                 
                 
                 String UserName = st.getString("USERNAME");
                 String Email = st.getString("EMAIL");
            
                 if(u==UserName && e==Email) {
                        // need to put different alerts
                 }else if(u==UserName && e!=Email) {
                        // need to put different alerts
                 }else if(u!=UserName && e==Email) {
                        // need to put different alerts
                 }else {
                    f=1; 
                 }

                 
            
             }while(f!=1);
                String q = "INSERT INTO UTENTI "
                        + " ( USERNAME ,EMAIL ,PASSWORD ,DATANASCITA ,RUOLO ) "
                        + " VALUES ('"+u+"','"+e+"','"+p+"','"+d+"','USER') ";
                int N = s.executeUpdate(q);
                
             if(N==1) {
                 infoAlert();
            
             }
             else {
                 warnAlert();
             }
         } catch (SQLException ex) {
             Logger.getLogger(LoginRegFxmlController.class.getName()).log(Level.SEVERE, null, ex);
         }
        
        }
    
    //Login
    
    @FXML
    private TextField usernameLog;
    
    @FXML
    private PasswordField passwordLog;
    
    @FXML
    private ProgressIndicator progressLog;
    
    
    
    @FXML
    private Button buttonLog;
    
    public void handleButtonClickLog() {
        
    }
    
    public void infoAlert() {
     Alert alertConf = new Alert(AlertType.INFORMATION,"", ButtonType.OK);
     alertConf.setTitle("Registrazione");
     alertConf.setHeaderText(null);
     alertConf.setContentText("Registrazione effettuata con successo");
     alertConf.getDialogPane().setPrefSize(200, 200);
     
     Optional<ButtonType> result  = alertConf.showAndWait();
     if(result.get() == ButtonType.OK) {
         
     } 
    }
     
     public void warnAlert() {
        Alert alertWarn = new Alert(AlertType.ERROR);
        alertWarn.setTitle("Errore");
        alertWarn.setHeaderText(null);
        alertWarn.setContentText("Errore nell'inserimento");
             
        Optional<ButtonType> result  = alertWarn.showAndWait();
        if(result.get() == ButtonType.OK) {
             
        } 
         
   }
   
}

Prompt errors

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
    at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1081)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:893)
    at [email protected]/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:1623)
Caused by: javafx.fxml.LoadException: 
/C:/Users/user/eclipse-workspace/LoginRegistrazioneDB/bin/application/LoginRegFxml.fxml:15

    at [email protected]/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2722)
    at [email protected]/javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:935)
    at [email protected]/javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:983)
    at [email protected]/javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:230)
    at [email protected]/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:757)
    at [email protected]/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2853)
    at [email protected]/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2649)
    at [email protected]/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2563)
    at [email protected]/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2531)
    at LoginRegistrazioneDB/application.LoginRegistrazioneDB.start(LoginRegistrazioneDB.java:16)
    at [email protected]/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
    at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
    at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
    at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
    at [email protected]/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at [email protected]/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at [email protected]/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:185)
    ... 1 more
Caused by: java.lang.ClassNotFoundException: LoginRegistrazioneDB/LoginRegFxmlController
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at [email protected]/javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:933)
    ... 17 more
Exception running application application.LoginRegistrazioneDB

Solution

  • Javafx problem that doesn't find the .fxml file even if they are in the same package.

    That's not the problem. The exception stacktrace says that JavaFX is not able to load a class:

    Caused by: java.lang.ClassNotFoundException: LoginRegistrazioneDB/LoginRegFxmlController
    

    The cause of the problem is in the .fxml file. It says:

    <VBox fx:controller="LoginRegistrazioneDB/LoginRegFxmlController" ...
    

    and

    <AnchorPane fx:controller="LoginRegistrazioneDB/LoginRegFxmlController" 
        id="AnchorPane" prefHeight="699.0" prefWidth="1061.0" 
        style="-fx-background-color: black;" 
        xmlns="http://javafx.com/javafx/8" 
        xmlns:fx="http://javafx.com/fxml/1"
        fx:controller="application.LoginRegFxmlController">
    

    but the LoginRegFxmlController is actually declared in the application package, not the LoginRegistrazioneDB package.

    So the classloader has been told to look for a class which doesn't exist!!

    You need to carefully review the .fxml file and make sure that the class and package names that you have used there match your code.


    (And AFAIK you shouldn't be using a / in the fx:controller values. The documentation uses a . in the classes FQN just like Java source code does.)

    (And you shouldn't have two fx:controller attributes in the AnchorPane element. That's wrong. It's not even valid XML.)