Search code examples
javaswingjtextfield

Problems with JTextField input exception check and input return


I have this code that calls a JFrame and asks for an input before returning that input.

Here's the code:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;

public class testing1 {

    public JFrame frame;
    public JTextField textField;
    String keyword;
    ClickHandler cl = new ClickHandler();
    JTextArea messageText;
    String NumberUnits;

    public static void main(String[] args) {
        testing1 t = new testing1();
        int NUnits = t.AskUnits(); 
        System.out.println("Number of Units: " + NUnits);   
    }

    private testing1() {
        frame = new JFrame();
        frame.getContentPane().setBackground(Color.WHITE);
        
        JPanel questionPanel = new JPanel();
        questionPanel.setBackground(Color.WHITE);
        
        textField = new JTextField();
        textField.setColumns(10);
        
        JPanel panel = new JPanel();
        panel.setBackground(Color.WHITE);
        GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
        groupLayout.setHorizontalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGroup(groupLayout.createSequentialGroup()
                    .addGap(99)
                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
                        .addGroup(groupLayout.createSequentialGroup()
                            .addGap(10)
                            .addComponent(textField, GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)
                            .addGap(11))
                        .addComponent(questionPanel, GroupLayout.DEFAULT_SIZE, 231, Short.MAX_VALUE))
                    .addGap(106))
                .addGroup(groupLayout.createSequentialGroup()
                    .addGap(132)
                    .addComponent(panel, GroupLayout.PREFERRED_SIZE, 173, GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(131, Short.MAX_VALUE))
        );
        groupLayout.setVerticalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGroup(groupLayout.createSequentialGroup()
                    .addContainerGap(38, Short.MAX_VALUE)
                    .addComponent(questionPanel, GroupLayout.PREFERRED_SIZE, 69, GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(ComponentPlacement.UNRELATED)
                    .addComponent(textField, GroupLayout.PREFERRED_SIZE, 19, GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(ComponentPlacement.RELATED)
                    .addComponent(panel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addGap(90))
        );
        
        messageText = new JTextArea();
        questionPanel.add(messageText);
        
        JButton okButton = new JButton("OK");
        okButton.setBackground(Color.WHITE);
        okButton.addActionListener(cl);
        okButton.setActionCommand("ok");
        panel.add(okButton);
        
        JButton cancelButton = new JButton("CANCEL");
        cancelButton.setBackground(Color.WHITE);
        cancelButton.addActionListener(cl);
        cancelButton.setActionCommand("cancel");
        panel.add(cancelButton);
        frame.getContentPane().setLayout(groupLayout);
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.setVisible(true);
    }
    
    public int AskUnits() {
        keyword = "AskUnits";
        messageText.setText("How many units are in this course?");
        NumberUnits = textField.getText(); 
//      String NumberUnits = JOptionPane.showInputDialog(null, "How many units are in this course?", courseName, JOptionPane.INFORMATION_MESSAGE);
            try {
                   int NumberofUnits = Integer.parseInt(NumberUnits); 
                    if (NumberofUnits < 0 || NumberofUnits > 100) {
                        JOptionPane.showMessageDialog(null, "Input out of bounds",
                                  "ERROR", JOptionPane.ERROR_MESSAGE);
                        System.exit(0);
                    }
                    return NumberofUnits;
                 } catch(NumberFormatException e) {
                    JOptionPane.showMessageDialog(null, "Input is not a number",
                              "ERROR", JOptionPane.ERROR_MESSAGE);
                    System.exit(0);
                 }
            return 0; 
    } // all clear
    
    public class ClickHandler implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            String yourChoice = event.getActionCommand();
            
            switch(keyword) {
            case "AskUnits":
                switch(yourChoice) {
                case "ok": System.out.println("OK GOT"); break;
                case "cancel": System.exit(0); break;
                }
                break;
            }
        }
    }
}

My problems with this code:

  1. Before even inputting the code, the "INPUT IS NOT A NUMBER" exception shows up.

  2. I want to receive the input NUnits before printing out the value of NUnits received from the input. However, the NUnits prints 0 before anything is input.


Solution

  • The exception is thrown because you're calling AskUnits() as soon as the program starts which starts input processing without giving the user a chance to enter a value. If you move the AskUnits() method call inside your click handler, the user will have a chance to enter a value and you can print it to the console once OK is clicked.

    If you're using the AskUnits() method to setup the screen (the question to ask, etc.) you should at least move the input processing code (everything below and including the NumberUnits = textField.getText() call) to a separate method which you can then call from the OK button's click handler to print the entered value.


    @camickr has given some good pointers on the Java naming conventions. Here's a good resource from Oracle that covers all other program identifiers as well. The page has been archived but the conventions haven't changed.

    From Code Conventions for the Java Programming Language

    Naming conventions make programs more understandable by making them easier to read.

    Something most SO members appreciate which in turn makes the questions more likely to receive help here.