Slayer Of Whales
Slayer Of Whales

Reputation: 83

JTextField.getText() inside of actionListener fails to return the proper String

I have run into the issue of not being able to collect the real text from my JTextField when calling getText(). I have provided a simplified version of the code I was running that includes only the aspects of the program to where it will reproduce the issue. I am attempting to collect the text from the JTextField upon the clicking of the button b.

The correct value returned from getText() should be what ever was input, but instead here it simply returns an empty String. In testing I have found that initializing the TJextField with a String will have it return that String no matter what, even if it is changed before pressing the button. and if one uses setText() inside of init() for example, it will continue to return an empty String.

public class TopClass {
    public static void main(String[] args){
        BottomClass bottom = new BottomClass();
        bottom.init();
    }
}

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class BottomClass implements ActionListener{
    JFrame frame = new JFrame();
    JTextField tf = new JTextField();
    JButton b = new JButton("BUTTON");

    public void init(){
        BottomClass bc = new BottomClass();
        b.addActionListener((ActionListener) bc);

        frame.add(tf, BorderLayout.NORTH);
        frame.add(b, BorderLayout.SOUTH);
        frame.setSize(100,100);
        frame.show();
    }


    public void actionPerformed(ActionEvent e) {
        System.out.println("TEXT: "+tf.getText());
    }
}

Upvotes: 0

Views: 604

Answers (1)

yur
yur

Reputation: 390

Several things aren't clean at all in this code, so I just rewrote most of BottomClass.

  1. You can do it by implementing ActionListener, but BottomClass is more than just an EventListener, so (in the name of realistic responsibility) I just added a new instance of ActionListener to the component that needs it (JButton)

  2. You create an instance bc of BottomClass inside the method init() IN BottomClass. This makes no sense at all and was simply deleted.

  3. You initialize your components at the wrong point. They should either be initialized in the constructor, or inside your nice and fitting init() method. I'm 99% sure that the placement of your initializations is what caused your trouble.

  4. I'm not sure how much of an error this is, but when adding your components you specify BorderLayout constraints despite never defining BorderLayout as the LayoutManager to use. I added the setLayout(new BorderLayout()) call.

  5. It's usually good form to have a constructor, especially if you have a different class calling it. Even if it's empty, a written empty constructor is more easily readable and understandable than an invisible one.

All that said, here's a working version of BottomClass, TopClass doesn't need any adjustments:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class BottomClass
{
    JFrame frame;
    JTextField tf;
    JButton b;
    
    public BottomClass() 
    {
        // Empty constructor
    }
    
    public void init()
    {
        frame = new JFrame();
        frame.setLayout(new BorderLayout());
        
        tf = new JTextField();
        
        b = new JButton("Button");
        b.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                System.out.println("TEXT: " + tf.getText());
            }
        });
        
        frame.add(tf, BorderLayout.NORTH);
        frame.add(b, BorderLayout.SOUTH);
        frame.setSize(100, 100);
        frame.setVisible(true);
    }
}

Upvotes: 2

Related Questions