0

This is the error.

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml@19-ea/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857)
    at javafx.fxml@19-ea/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1724)
    at javafx.base@19-ea/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base@19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@19-ea/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19-ea/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@19-ea/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base@19-ea/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@19-ea/javafx.scene.Node.fireEvent(Node.java:8797)
    at javafx.controls@19-ea/javafx.scene.control.Button.fire(Button.java:203)
    at javafx.controls@19-ea/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
    at javafx.controls@19-ea/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base@19-ea/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base@19-ea/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base@19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@19-ea/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19-ea/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@19-ea/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base@19-ea/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@19-ea/javafx.scene.Scene$MouseHandler.process(Scene.java:3881)
    at javafx.graphics@19-ea/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
    at javafx.graphics@19-ea/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2607)
    at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
    at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics@19-ea/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
    at javafx.graphics@19-ea/com.sun.glass.ui.View.notifyMouse(View.java:937)
    at javafx.graphics@19-ea/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics@19-ea/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: 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 com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:77)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    at javafx.base@19-ea/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml@19-ea/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:84)
    at javafx.fxml@19-ea/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1852)
    ... 46 more
Caused by: java.lang.NumberFormatException: For input string: ""
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
    at java.base/java.lang.Integer.parseInt(Integer.java:675)
    at java.base/java.lang.Integer.valueOf(Integer.java:992)
    at com.example.studentdatabase/com.example.studentdatabase.Register.register(Register.java:99)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    ... 53 more

These are my classes and FXMLs

Main class -

package com.example.studentdatabase;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class Main extends Application {

    InputStream stream = new FileInputStream("C:\\Users\\dinira francisco\\Desktop\\DDSlogo.jpg");
    Image image  = new Image(stream);

    public Main() throws FileNotFoundException {
    }

    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("Register.fxml"));
        Scene scene = new Scene(fxmlLoader.load());
        stage.setTitle("Student Database 2023");
        stage.getIcons().add(image);
        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
    }

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

Register class -

package com.example.studentdatabase;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Statement;

public class Register {
    private int studentID=0;

    private boolean hasFirstName = false;
    private boolean hasLastName = false;
    private boolean hasAge = false;
    private boolean hasGrade = false;
    @FXML
    private TextField GradeTF;

    @FXML
    private Button ageSubmit;

    @FXML
    private TextField ageTF;

    @FXML
    private TextField firstNameTF;

    @FXML
    private Button firstSubmit;

    @FXML
    private Button gradeSubmit;

    @FXML
    private TextField lastNameTF;

    @FXML
    private Button lastsubmit;

    @FXML
    private Button registerButton;

    @FXML
    private Label warning;

    public void getFirstName(ActionEvent event){
        if(firstNameTF.getText().length()>=1){
            hasFirstName=true;
            firstNameTF.setDisable(true);
        }
    }

    public void getLastName(ActionEvent event){
        if(lastNameTF.getText().length()>=1){
            hasLastName=true;
            lastNameTF.setDisable(true);
        }
    }

    public void getAge(ActionEvent event){
        if(ageTF.getText().length()>=1){
            hasAge=true;
            ageTF.setDisable(true);
        }
    }

    public void getGrade(ActionEvent event){
        if(GradeTF.getText().length()>=1){
            hasGrade=true;
            GradeTF.setDisable(true);
        }
    }

    public void register(ActionEvent event){
        if(hasFirstName && hasLastName && hasAge && hasGrade){
            studentID++;
            warning.setText("Registration Completed!");
            warning.setVisible(true);
            firstNameTF.setText("");
            lastNameTF.setText("");
            ageTF.setText("");
            GradeTF.setText("");
            firstNameTF.setDisable(false);
            lastNameTF.setDisable(false);
            ageTF.setDisable(false);
            GradeTF.setDisable(false);
            hasFirstName=false;
            hasLastName = false;
            hasAge = false;
            hasGrade = false;
            DatabaseConnection databaseConnection = new DatabaseConnection();
            Connection connection = databaseConnection.getConnection();

            String registerString = "INSERT INTO student_data(student_id,first_name,last_name,age,grade) VALUES('"+studentID+"','"+firstNameTF.getText()+"','"+lastNameTF.getText()+"','"+Integer.valueOf(ageTF.getText())+"','"+Integer.valueOf(GradeTF.getText())+"')";
            try{
                Statement statement = connection.createStatement();
                statement.executeUpdate(registerString);
            }catch(Exception e){
                e.printStackTrace();
                e.getCause();
            }
        }else{
            warning.setText("Fields are Empty!");
            warning.setVisible(true);
        }
    }
}

Database Connection class -

package com.example.studentdatabase;

import java.sql.Connection;
import java.sql.DriverManager;

public class DatabaseConnection {
    public Connection databaseLink;

    public Connection getConnection(){
        String databaseName = "student_db";
        String databaseUser = "root";
        String databasePassword = "***";
        String url = "jdbc:mysql://localhost/"+databaseName;
        try{
            Class.forName("com.mysql.cj.jdbc.Driver");
            databaseLink = DriverManager.getConnection(url,databaseUser,databasePassword);
        }catch (Exception e){
            e.printStackTrace();
            e.getCause();
        }
        return databaseLink;
    }
}

and FXML -

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane prefHeight="443.0" prefWidth="458.0" style="-fx-background-color: #f0db24;" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.studentdatabase.Register">
   <children>
      <Label layoutX="161.0" layoutY="25.0" text="Student Database">
         <font>
            <Font size="17.0" />
         </font>
      </Label>
      <Label layoutX="95.0" layoutY="52.0" text="Sinhala Oratory &amp; Debating Society">
         <font>
            <Font size="17.0" />
         </font>
      </Label>
      <Label layoutX="106.0" layoutY="78.0" text="D.S.Senanayake College - Col. 08">
         <font>
            <Font size="17.0" />
         </font>
      </Label>
      <Label layoutX="161.0" layoutY="125.0" text="Registration Form">
         <font>
            <Font size="17.0" />
         </font>
      </Label>
      <Label layoutX="66.0" layoutY="177.0" text="First Name ">
         <font>
            <Font size="15.0" />
         </font>
      </Label>
      <Label layoutX="67.0" layoutY="226.0" text="Last Name ">
         <font>
            <Font size="15.0" />
         </font>
      </Label>
      <Label layoutX="66.0" layoutY="269.0" text="Age">
         <font>
            <Font size="15.0" />
         </font>
      </Label>
      <Label layoutX="66.0" layoutY="315.0" text="Grade">
         <font>
            <Font size="15.0" />
         </font>
      </Label>
      <TextField fx:id="firstNameTF" layoutX="154.0" layoutY="175.0" />
      <TextField fx:id="lastNameTF" layoutX="154.0" layoutY="224.0" />
      <TextField fx:id="ageTF" layoutX="154.0" layoutY="267.0" />
      <TextField fx:id="GradeTF" layoutX="154.0" layoutY="313.0" />
      <Button fx:id="firstSubmit" layoutX="318.0" layoutY="175.0" mnemonicParsing="false" onAction="#getFirstName" text="Submit" />
      <Button fx:id="gradeSubmit" layoutX="318.0" layoutY="313.0" mnemonicParsing="false" onAction="#getGrade" text="Submit" />
      <Button fx:id="ageSubmit" layoutX="318.0" layoutY="267.0" mnemonicParsing="false" onAction="#getAge" text="Submit" />
      <Button fx:id="lastsubmit" layoutX="318.0" layoutY="224.0" mnemonicParsing="false" onAction="#getLastName" text="Submit" />
      <Button fx:id="registerButton" layoutX="192.0" layoutY="358.0" mnemonicParsing="false" onAction="#register" text="Register" />
      <Label fx:id="warning" layoutX="175.0" layoutY="399.0" text="Fields are Empty!" textFill="#f70909" visible="false" />
   </children>
</AnchorPane>

I searched some solutions in stackoverflow but couldn't solve the issue.

Abra
  • 19,142
  • 7
  • 29
  • 41
  • The stack trace tells you the problem: `Caused by: java.lang.NumberFormatException: For input string: "" ... at com.example.studentdatabase/com.example.studentdatabase.Register.register(Register.java:99)` – James_D Jan 28 '23 at 19:20
  • 2
    You set the text of `ageTF` to an empty string:- `ageTF.setText("");`. Then you try to convert that empty string to an `Integer`:- `Integer.valueOf(ageTF.getText())` Obviously an empty string cannot be converted to an `Integer` and therefore you are getting (in the stack trace):- `java.lang.NumberFormatException: For input string: ""` – Abra Jan 28 '23 at 19:28
  • The question should not be just in the subject. Please use the subject as a summarised few words to get the attention and explain the question in the body. – Lakshitha Jan 28 '23 at 20:38

1 Answers1

1

First some notes about your code.

Class DatabaseConnection
Class.forName("com.mysql.cj.jdbc.Driver");

This is no longer needed.

Because of the catch block in method getConnection, the method may return null which means that other methods, that call method getConnection, need to check if null was returned. In my opinion, better to declare that method getConnection throws SQLException. Also, class DatabaseConnection should probably be a singleton which means that method getConnection should be a static method.

Class Register

I think that you should use PreparedStatement rather than Statement.

You should also use try-with-resources

I don't see the need for this line:

e.getCause();

Method printStackTrace will also print the cause – if there is one.

Rather than using variables hasFirstName, hasLastName, hasAge and hasGrade, use bindings which you can set up in method initialize since class Register is your FXML controller. Then you don't need a Submit button for every TextField in your registration form. Data entry forms usually don't require submitting each field individually.

Rather than explicitly setting sizes and locations for each Node, better to use layouts.

Regarding the top Label, you can use a single Label rather than a separate Label for each line of text. You can insert line breaks and you can center align the text.

Now to your problem. You need to "clear" the registration form after you have updated the database (and not before, as you are currently doing in your code).

Here is my version of your application.

Class DatabaseConnection

package com.example.studentdatabase;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseConnection {
    private static Connection databaseLink;

    public static Connection getConnection() throws SQLException {
        if (databaseLink == null) {
            String databaseName = "student_db";
            String databaseUser = "root";
            String databasePassword = "***";
            String url = "jdbc:mysql://localhost/" + databaseName;
            databaseLink = DriverManager.getConnection(url, databaseUser, databasePassword);
        }
        return databaseLink;
    }
}

Class Register
Note that it uses text blocks. It also uses [JavaFX] alerts.

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import java.sql.Connection;
import java.sql.PreparedStatement;

public class Register {
    private int studentID = 0;

    @FXML
    private TextField gradeTF;

    @FXML
    private TextField ageTF;

    @FXML
    private TextField firstNameTF;

    @FXML
    private TextField lastNameTF;

    @FXML
    private Button registerButton;

    public void register(ActionEvent event) {
        String registerString = """
INSERT INTO student_data (student_id, first_name, last_name, age, grade)
VALUES (?, ?, ?, ?, ?)
                    """;
        try (Connection connection = DatabaseConnection.getConnection();
             PreparedStatement statement = connection.prepareStatement(registerString)) {
            statement.setInt(1, ++studentID);
            statement.setString(2, firstNameTF.getText());
            statement.setString(3, lastNameTF.getText());
            statement.setInt(4, Integer.valueOf(ageTF.getText()));
            statement.setInt(5, Integer.valueOf(gradeTF.getText()));
            statement.executeUpdate();
            Alert alert = new Alert(AlertType.INFORMATION);
            alert.setContentText("Registration Completed!");
            alert.setHeaderText(null);
            alert.showAndWait();
            firstNameTF.setText("");
            lastNameTF.setText("");
            ageTF.setText("");
            gradeTF.setText("");
            firstNameTF.setDisable(false);
            lastNameTF.setDisable(false);
            ageTF.setDisable(false);
            gradeTF.setDisable(false);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void initialize() {
        registerButton.disableProperty().bind(firstNameTF.textProperty().isEmpty()
                                          .or(lastNameTF.textProperty().isEmpty())
                                          .or(ageTF.textProperty().isEmpty())
                                          .or(gradeTF.textProperty().isEmpty()));
    }
}

FXML file

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.text.Font?>

<BorderPane style="-fx-background-color: #f0db24;" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.studentdatabase.Register">
   <top>
      <Label text="Student Database&#xD;Sinhala Oratory &amp; Debating Society&#xD;D.S.Senanayake College - Col. 08&#xD;Registration Form">
         <font>
            <Font size="17.0" />
         </font>
         <textAlignment>CENTER</textAlignment>
      </Label>
      <BorderPane.margin>
          <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
      </BorderPane.margin>
   </top>
   <center>
      <GridPane hgap="10.0" vgap="10.0">
         <alignment>CENTER</alignment>
         <children>
            <Label text="First Name">
               <font>
                  <Font size="15.0" />
               </font>
               <GridPane.rowIndex>0</GridPane.rowIndex>
               <GridPane.columnIndex>0</GridPane.columnIndex>
            </Label>
            <TextField fx:id="firstNameTF">
                  <GridPane.rowIndex>0</GridPane.rowIndex>
                  <GridPane.columnIndex>1</GridPane.columnIndex>
            </TextField>
            <Label text="Last Name">
               <font>
                  <Font size="15.0" />
               </font>
               <GridPane.rowIndex>1</GridPane.rowIndex>
               <GridPane.columnIndex>0</GridPane.columnIndex>
            </Label>
            <TextField fx:id="lastNameTF">
                  <GridPane.rowIndex>1</GridPane.rowIndex>
                  <GridPane.columnIndex>1</GridPane.columnIndex>
            </TextField>
            <Label text="Age">
               <font>
                  <Font size="15.0" />
               </font>
               <GridPane.rowIndex>2</GridPane.rowIndex>
               <GridPane.columnIndex>0</GridPane.columnIndex>
            </Label>
            <TextField fx:id="ageTF">
                  <GridPane.rowIndex>2</GridPane.rowIndex>
                  <GridPane.columnIndex>1</GridPane.columnIndex>
            </TextField>
            <Label text="Grade">
               <font>
                  <Font size="15.0" />
               </font>
               <GridPane.rowIndex>3</GridPane.rowIndex>
               <GridPane.columnIndex>0</GridPane.columnIndex>
            </Label>
            <TextField fx:id="gradeTF">
                  <GridPane.rowIndex>3</GridPane.rowIndex>
                  <GridPane.columnIndex>1</GridPane.columnIndex>
            </TextField>
         </children>
      </GridPane>
      <BorderPane.margin>
          <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
      </BorderPane.margin>
   </center>
   <bottom>
      <Button fx:id="registerButton" mnemonicParsing="false" onAction="#register" text="Register" />
      <BorderPane.alignment>CENTER</BorderPane.alignment>
      <BorderPane.margin>
          <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
      </BorderPane.margin>
   </bottom>
</BorderPane>

Class Main was not changed and so is omitted.

Abra
  • 19,142
  • 7
  • 29
  • 41