-1

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 javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics@20.0.1/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 javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:893)
    at javafx.graphics@20.0.1/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 javafx.fxml@20.0.1/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2722)
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:935)
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:983)
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:230)
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:757)
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2853)
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2649)
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2563)
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2531)
    at LoginRegistrazioneDB/application.LoginRegistrazioneDB.start(LoginRegistrazioneDB.java:16)
    at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
    at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
    at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
    at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
    at javafx.graphics@20.0.1/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at javafx.graphics@20.0.1/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics@20.0.1/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 javafx.fxml@20.0.1/javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:933)
    ... 17 more
Exception running application application.LoginRegistrazioneDB
Lyr
  • 3
  • 2
  • 4
    here's your problem: java.lang.ClassNotFoundException: LoginRegistrazioneDB/LoginRegFxmlController – Stultuske May 24 '23 at 09:06
  • 1
    time to work through a tutorial on fxml to learn how to set the controller attribute correctly – kleopatra May 24 '23 at 09:24
  • Will do @kleopatra – Lyr May 24 '23 at 12:58
  • If you use an IDE such as Idea Community Edition (which I recommend for JavaFX development), it will highlight issues like this in the editor when you open the FXML file. – jewelsea May 24 '23 at 23:06
  • Unrelated recommendations. Use a modern JavaFX version, e.g. 20 (documented at [openjfx.io](https://openjfx.io)) rather than obsolete versions such as JavaFX 8. Don't rely too much on AnchorPanes because they work mainly with absolute positioning (use other [pane types](https://docs.oracle.com/javase/8/javafx/layout-tutorial/builtin_layouts.htm)). Limit hardcoding of layout positions and sizes. Place styles in CSS stylesheets, not inline in FXML. Don't write database code in controllers (extract it to separate unit testable classes). – jewelsea May 24 '23 at 23:10
  • Use IDE [code formatting](https://www.jetbrains.com/help/idea/reformat-and-rearrange-code.html). Understand when to use [== and equals](https://stackoverflow.com/questions/7520432/what-is-the-difference-between-and-equals-in-java). Use [prepared statements](https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html). Use [password hashing](https://auth0.com/blog/hashing-passwords-one-way-road-to-security/) unless security is unimportant (and then a password is not needed). – jewelsea May 24 '23 at 23:12
  • @jewelsea i already use a javaFx 20 sdk as you can see in the output, then password hashing is another thing that i have to implement but i wrote it in Italian sorry for the mistake – Lyr May 25 '23 at 06:01
  • And now i changed to intellij that is far better than eclipse that i used only because i didn't know any other IDEs other than netbeans that doesn't work in my laptop – Lyr May 25 '23 at 06:05
  • Yes now I see the references to 20 in the stack trace. In the fxml you set the namespace to Java 8 on the AnchorPane, which is wrong, which is why I was confused. – jewelsea May 25 '23 at 09:48

1 Answers1

3

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.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thank you so much guys i was struggling to see the problem, and my teacher doesn't deal with javafx so bless you for your kindness – Lyr May 24 '23 at 12:49