0

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.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
leah
  • 61
  • 7
  • 2
    (1-) 1) Class names SHOULD start with an upper case character. 2) Variable names should NOT start with an upper case character 3) method names should NOT start with an upper case character. You were given advice in your last question learn Java naming conventions. – camickr Jul 31 '21 at 02:32
  • You need to learn about event driven coding. Code should generally be execute on user events like clicking a button or typing text. You invoke the "askUnits()" method as soon as the frame is displayed so the user doesn't have an opportunity to enter any text. Why would you comment out the usage of the JOptionPane? That dialog will block allowing the user time to enter the text. I'm really not sure how any of that code works. You need to set a layout manager BEFORE you add component to the frame or panel. – camickr Jul 31 '21 at 02:37
  • @camickr good points on the naming convention there. I suppose, OP is coming from the .NET world. No excuse for flouting the conventions *again*, though. – Ravi K Thapliyal Jul 31 '21 at 02:48
  • *"calls a `JFrame` and asks for an input"* For input, use a modal dialog. Even simpler, use a `JOptionPane.showInputDialog(..)`. This not only solves the stated problem (the input will be passed back as a `String` when the dialog closes) but also avoids using more than one `JFrame` (a no-no). – Andrew Thompson Jul 31 '21 at 03:31
  • @Andrew Thompson. Thanks for the reply! My original program was written with JOptionPanes but I want to create a better-looking interface so I decided to attempt to switch it over to JFrames, which is not going that smoothly right now. – leah Jul 31 '21 at 03:57
  • Then put whatever is in the frame, into a modal `JDialog`! It will have the same effect. The values can be obtained the next code line after it is set visible.. – Andrew Thompson Jul 31 '21 at 04:00
  • *I want to create a better-looking interface* - you are still not understanding how to create an event driven interface. If you want to "prompt" for a single piece of data then you use a JOptionPane as I suggested earlier. If you are creating a "form" with multiple pieces of data like "first name" and "last name" then you create a modal JDialog and add a JButton to validate/process the data when the user is finished entering the data. Learn from real world applications. – camickr Jul 31 '21 at 13:50
  • @camickr sorry! I wasn't aware that I was supposed to accept an answer. Thanks for the heads up! Also, yeah I'm figuring out everything using trial and error and I'm not sure how to create an event driven interface. I'll look into the methods you suggest, thanks! – leah Jul 31 '21 at 15:29
  • @Andrew Thompson. Alright, I'll look into it. Thanks! – leah Jul 31 '21 at 15:31
  • @leah *I wasn't aware that I was supposed to accept an answer.* - you were also given that advice in your previous question: https://stackoverflow.com/questions/68424889/gridbaglayout-formatting-for-jbuttons – camickr Jul 31 '21 at 19:56

1 Answers1

2

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.

Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89