3

I'm trying to learn Swing and JFrame, so I'm creating a really simple program that asks for your name and then displays a box telling you what you've entered. I'm trying to use a separate class from the first to act as the ActionListener and display the name that was typed in. However it's not working for me. I tried creating a constructor in the second class that sets an instance variable to the value taken in the JTextfield but it's not showing up as I expected. Please have a look;

The prompt screen

I want it to say "You've Submitted the name Imray"

And here's my code (I've imported all libraries properly but omitted for space's sake)

This is the main class...

public class NamePrompt extends JFrame{


    private static final long serialVersionUID = 1L;

    String name;

    public NamePrompt(){

        setLayout(new BorderLayout());

        JLabel enterYourName = new JLabel("Enter Your Name Here:");
        JTextField textBoxToEnterName = new JTextField(21);
        JPanel panelTop = new JPanel();
        panelTop.add(enterYourName);
        panelTop.add(textBoxToEnterName);

        JButton submit = new JButton("Submit");
        submit.addActionListener(new SubmitButton(textBoxToEnterName.getText()));
        JPanel panelBottom = new JPanel();
        panelBottom.add(submit);

        //Add panelTop to JFrame
        add(panelTop, BorderLayout.NORTH);
        add(panelBottom, BorderLayout.SOUTH);

        //JFrame set-up
        setTitle("Name Prompt Program");
        //setSize(300, 150);
        pack();
        setLocationRelativeTo(null);


    }



public static void main(String[] args) {
    NamePrompt promptForName = new NamePrompt();
    promptForName.setVisible(true); 
}

}

And this is the ActionListener class:

public class SubmitButton implements ActionListener {

    String nameInput;

    public SubmitButton(String textfield){
        nameInput = textfield;
    }

    @Override
    public void actionPerformed(ActionEvent submitClicked) {
        Component frame = new JFrame();
        JOptionPane.showMessageDialog(frame , "You've Submitted the name " + nameInput );
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
CodyBugstein
  • 21,984
  • 61
  • 207
  • 363
  • BTW - this is a frame, but should be a blocking dialog or a `JOptionPane`. Something like [`showInputDialog(parent,"Enter your name")`](http://docs.oracle.com/javase/7/docs/api/javax/swing/JOptionPane.html#showInputDialog%28java.awt.Component,%20java.lang.Object%29) seems perfect for this use. – Andrew Thompson Dec 05 '12 at 07:21

3 Answers3

5

You are passing in an empty String into the ActionListener class SubmitButton when it is created and it is never updated once the text changes in the JTextField textBoxToEnterName so nothing is ever displayed.

You could pass the textBoxToEnterName JTextField to gain access to the value when required:

class SubmitButtonListener implements ActionListener {

    private JTextField textfield;

    public SubmitButtonListener(JTextField textfield) {
        this.textfield = textfield;
    }

    @Override
    public void actionPerformed(ActionEvent submitClicked) {
        Component frame = new JFrame();
        JOptionPane.showMessageDialog(frame, "You've Submitted the name "
                + textfield.getText());
    }
}
Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • But textBoxToEnterName is in a different class. It's meaningless in this class, right? – CodyBugstein Dec 05 '12 at 00:14
  • Where would that setter method be called? – CodyBugstein Dec 05 '12 at 00:19
  • It works!! But why does it work... when I pass the JTextfield through the constructor, it's just as empty as when there was a String there. Even though you're eventually calling 'getText' on a local JTextfield, isn't it empty at that point? Why can it all the sudden read the name? – CodyBugstein Dec 05 '12 at 00:30
  • 1
    If you use the `JTextField` rather than `String`, you have access to the 'live' value from the component. – Reimeus Dec 05 '12 at 00:31
  • wow so cool. I gotta play more with this. Thanks so much Reimeus! – CodyBugstein Dec 05 '12 at 00:33
2

I think you should have the SubmitButton class as an inner class of the NamePrompt class. This way you can use the text field's variable without having to pass it along to a new class, which might complicate things.

class SubmitButton implements ActionListener {

//     Do not need this
   // public SubmitButton(String textfield){
     //   nameInput = textfield;
   // }

@Override
public void actionPerformed(ActionEvent submitClicked) {
    Component frame = new JFrame();
    JOptionPane.showMessageDialog(frame , "You've Submitted the name " + textBoxToEnterName.getText());
}

But be sure to define the variables outside of the constructor so it can be used by the inner class:

public class NamePrompt extends JFrame{


private static final long serialVersionUID = 1L;

JLabel enterYourName;
JextField textBoxToEnterName;
JPanel panelTop;
JButton submit; 
JPanel panelBottom;

String name;

public NamePrompt(){ ..... (set up the variables here)

The final class would look like:

    public class NamePrompt extends JFrame{


        private static final long serialVersionUID = 1L;

        String name;
        JLabel enterYourName;
        JTextField textBoxToEnterName;
        JPanel panelTop;
        JButton submit;
        JPanel panelBottom;


        public NamePrompt(){

            setLayout(new BorderLayout());

            enterYourName = new JLabel("Enter Your Name Here:");
            textBoxToEnterName = new JTextField(21);
            panelTop = new JPanel();
            panelTop.add(enterYourName);
            panelTop.add(textBoxToEnterName);

            submit = new JButton("Submit");
            submit.addActionListener(new SubmitButton(textBoxToEnterName.getText()));
            panelBottom = new JPanel();
            panelBottom.add(submit);

            //Add panelTop to JFrame
            add(panelTop, BorderLayout.NORTH);
            add(panelBottom, BorderLayout.SOUTH);

            //JFrame set-up
            setTitle("Name Prompt Program");
            //setSize(300, 150);
            pack();
            setLocationRelativeTo(null);
    }

    class SubmitButton implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent submitClicked) {
            Component frame = new JFrame();
            JOptionPane.showMessageDialog(frame , "You've Submitted the name " + textBoxToEnterName.getText());
        }
    }



    public static void main(String[] args) {
        NamePrompt promptForName = new NamePrompt();
        promptForName.setVisible(true); 
    }
}
SamIAm
  • 2,241
  • 6
  • 32
  • 51
  • In the top box, how can you use 'textBoxToEnterName.getText()', it hasn't been defined in the class (you commented it out) nor has it been passed as a parameter. ? – CodyBugstein Dec 05 '12 at 00:35
  • 1
    I actually used it all in one class. So it's all within one class and not two separate class. If you put it within two classes, I think it might complicate things. – SamIAm Dec 05 '12 at 00:37
  • I wanted to try it in two classes, it's more satisfying. Thanks to @Reimeus it works in two, but I really appreciate this solution as well. Thank you! – CodyBugstein Dec 05 '12 at 00:46
1

There is the problem:

submit.addActionListener(new SubmitButton(textBoxToEnterName.getText()))

To the listener you are passing a String instead of the textfield, change it to accept textfield :)

And at

public void actionPerformed(ActionEvent submitClicked) {
        Component frame = new JFrame();
        JOptionPane.showMessageDialog(frame , "You've Submitted the name " + nameInput );
    }

ask the textfield current value

  • So I've tried 'submit.addActionListener(new SubmitButton(textBoxToEnterName)' but it's still not working... I understand what I'm doing wrong, but I can't figure out the solution – CodyBugstein Dec 05 '12 at 00:18
  • for you is better search a bit with the following keyword: "pass by reference vs pass by value" it will help you in many-many cases in your programming carier. –  Dec 05 '12 at 00:37