JTextField.getText() 在 actionListener 内部无法返回正确的字符串。

huangapple go评论74阅读模式
英文:

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

问题

以下是您要翻译的内容:

我遇到了一个问题,即在调用getText()时无法收集来自我的JTextField的实际文本。我提供了一个简化版本的代码,其中仅包括程序的一些方面,以便复现此问题。我试图在单击按钮b时收集来自JTextField的文本。

从getText()返回的正确值应该是用户输入的内容,但在这里它只返回一个空字符串。在测试中,我发现使用一个字符串初始化TJextField将导致它无论如何都返回该字符串,即使在按下按钮之前进行更改。如果在init()内部使用setText(),它仍然会返回一个空字符串。

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());
    }
}
英文:

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());
    }
}

答案1

得分: 2

这段代码中有几个问题,因此我重新编写了BottomClass的大部分内容。

  1. 您可以通过实现ActionListener来实现此功能,但是BottomClass不仅仅是一个事件监听器,因此(为了负责任地处理实际责任),我只是向需要它的组件(JButton)添加了一个新的ActionListener实例。

  2. BottomClassinit()方法内部创建了一个bcBottomClass实例,这毫无意义,因此被删除。

  3. 您在错误的地方初始化了组件。它们应该在构造函数中初始化,或者在您的init()方法中初始化。我99%确定,您的初始化放置位置导致了问题。

  4. 我不确定这有多大的错误,但在添加组件时,您指定了BorderLayout的约束条件,尽管从未将BorderLayout定义为要使用的布局管理器。我添加了setLayout(new BorderLayout())调用。

  5. 通常最好有一个构造函数,尤其是如果有其他类在调用它。即使是空的构造函数,一个写出来的空构造函数比一个看不见的构造函数更容易阅读和理解。

总之,这是BottomClass的工作版本,TopClass不需要任何调整:

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() 
    {
        // 空构造函数
    }
    
    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);
    }
}
英文:

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);
    }
}

huangapple
  • 本文由 发表于 2020年7月31日 13:32:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/63186277.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定