Search code examples
javaswingnumberformatexception

How can I get the inputs after the OK button is clicked?


I am new to Java and encountered a situation which is very annoying and I cannot even figure it out after three days. I am gonna post my code first.

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;

public class StudentInfo extends JFrame {

ArrayList<Student> lstStudent = new ArrayList<Student>();

private JTable table = null;
private JButton btnAdd = null;

public StudentInfo() {
    table = new JTable();
    btnAdd = new JButton("Add");
    this.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
    this.getContentPane().add(btnAdd, BorderLayout.SOUTH);
    this.setSize(600, 400);
    this.setVisible(true);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);

    updateTable();

    btnAdd.addActionListener(event -> {
        addStudent();
    });
}

public void addStudent() {
    StudentDetailDialog dialog = new StudentDetailDialog();
    Student student = new Student();
    student = dialog.dialog2Student();
    updateTable();
}

public void updateTable() {
    if(lstStudent.size() > 0) {
        Vector<Vector<Object>> tableData = new Vector<>();
        for(Student tempStudent : lstStudent) {
            Vector<Object> rowData = new Vector<>();
            rowData.add(tempStudent.getGiven());
            rowData.add(tempStudent.getLast());
            rowData.add(tempStudent.getGender());
            rowData.add(tempStudent.getAge());
            tableData.add(rowData);
        }

        Vector<String> colLabel = new Vector<>();
        colLabel.addAll(Arrays.<String> asList("Given Name", "Last Name", "Gender", "Age"));
        table.setModel(new DefaultTableModel(tableData, colLabel));
    }
    else {
        table.setModel(new DefaultTableModel(new Vector<>(), new Vector<>()));
    }
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        new StudentInfo();
    });
}
}

class StudentDetailDialog extends JDialog {

private JLabel lblGiven = null;
private JTextField txtGiven = null;
private JLabel lblLast = null;
private JTextField txtLast = null;
private JLabel lblGender = null;
private JTextField txtGender = null;
private JLabel lblAge = null;
private JTextField txtAge = null;

private JButton btnOK = null;
private JButton btnCancel = null;

public StudentDetailDialog() {
    JPanel pnlCenter = new JPanel(new GridLayout(4, 2));
    lblGiven = new JLabel("Given Name:");
    txtGiven = new JTextField(10);
    lblLast = new JLabel("Last Name:");
    txtLast = new JTextField(10);
    lblGender = new JLabel("Gender:");
    txtGender = new JTextField(10);
    lblAge = new JLabel("Age:");
    txtAge = new JTextField(10);
    pnlCenter.add(lblGiven);
    pnlCenter.add(txtGiven);
    pnlCenter.add(lblLast);
    pnlCenter.add(txtLast);
    pnlCenter.add(lblGender);
    pnlCenter.add(txtGender);
    pnlCenter.add(lblAge);
    pnlCenter.add(txtAge);

    JPanel pnlSouth = new JPanel();
    btnOK = new JButton("OK");
    btnCancel = new JButton("Cancel");
    pnlSouth.add(btnOK);
    pnlSouth.add(btnCancel);

    this.add(pnlCenter, BorderLayout.CENTER);
    this.add(pnlSouth, BorderLayout.SOUTH);
    this.setSize(250, 200);
    this.setVisible(true);
    this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

    btnOK.addActionListener(event -> {
        dispose();
    });

    btnCancel.addActionListener(event -> {
        dispose();
    });
}

public Student dialog2Student() {
    Student student = new Student();
    student.setGiven(txtGiven.getText());
    student.setLast(txtLast.getText());
    student.setGender(txtGender.getText());
    student.setAge(Integer.valueOf(txtAge.getText()));
    return student;
}
}

class Student {
private String givenName = null;
private String lastName = null;
private String gender = null;
private int age = 0;

public void setGiven(String givenName) {
    this.givenName = givenName;
}

public String getGiven() {
    return givenName;
}

public void setLast(String lastName) {
    this.lastName = lastName;
}

public String getLast() {
    return lastName;
}

public void setGender(String gender) {
    this.gender = gender;
}

public String getGender() {
    return gender;
}

public void setAge(int age) {
    this.age = age;
}

public int getAge() {
    return age;
}
}

what I want to do is to create a table and add some students to it. But after clicking the "add" button, some error immediately throws and I even have no time to input a word. What can I do to figure it out? And the error message is attached below.

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.valueOf(Unknown Source)
at class_demo.StudentDetailDialog.dialog2Student(StudentInfo.java:137)
at class_demo.StudentInfo.addStudent(StudentInfo.java:46)
at class_demo.StudentInfo.lambda$0(StudentInfo.java:39)
at class_demo.StudentInfo$$Lambda$27/32103433.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Hope you all understand what I am saying 'cause I am not a native speaker. Anyway, thank you guys!


Solution

  • As noted in my comment, your exception message is telling you exactly what's wrong -- you're trying to parse an empty String, "" to a number, and the line that it occurs on: student.setAge(Integer.valueOf(txtAge.getText()));

    The problems include

    • Your JDialog is non-modal, so that your code to extract the data from the dialog is called before the user has had a chance to interact with the dialog.
    • Solve this by making the dialog modal by calling the appropriate super constructor in the JDialog constructor, the one that uses a ModalityType parameter.
    • Don't set the dialog visible in the constructor as this will now freeze all constructor code below the setVisible(true) call, rendering your program useless.
    • Instead let the calling code call set visible on the dialog after it is fully constructed.
    • Your dialog's btnOK and btnCancel ActionListeners are identical, and so your program has no way of knowing which button the user presses. You can solve this by giving your dialog a state variable of some type, and setting it from within these ActionListeners before dispose is called.