Java Swing getText赢得';无法读取用户输入

Java Swing getText赢得';无法读取用户输入,java,swing,Java,Swing,我一直在努力使我正在开发的应用程序的GUI正常运行,而且,在Swing中做任何事情都已经很久了。大部分东西都回来了,但不是这个。我无法理解为什么在所有不同的文本组件中,如果我在其中键入了一些内容,getText()将始终返回“”而不管结果如何。如果我使用setText()作为测试,它将正确返回,但这并没有真正的帮助 这在JTextArea/JTextField、引用文本字段的各种方式(直接变量与从HashMap中提取)之间保持一致,并且不管访问的线程是什么类型的。有时,我使用调试器尝试通过其他测

我一直在努力使我正在开发的应用程序的GUI正常运行,而且,在Swing中做任何事情都已经很久了。大部分东西都回来了,但不是这个。我无法理解为什么在所有不同的文本组件中,如果我在其中键入了一些内容,getText()将始终返回“”而不管结果如何。如果我使用setText()作为测试,它将正确返回,但这并没有真正的帮助

这在JTextArea/JTextField、引用文本字段的各种方式(直接变量与从HashMap中提取)之间保持一致,并且不管访问的线程是什么类型的。有时,我使用调试器尝试通过其他测试片段查看正在发生的事情,但仍然一无所获。自编辑以来,我们已删除了许多此类案例,但问题仍然存在

在所有情况下,都不会获取用户输入

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class LifePathUI2 {

     final static boolean shouldWeightX = true;
     private GridBagConstraints cons;
     private BorderLayout windowLayout;
     private GridBagLayout layout;
     private JFrame mainWindow;
     private JPanel mainPanel;


     private JComponent currentComponent;
     private JTextField characterName;

    /**
     * @throws HeadlessException
     */
    public LifePathUI2() throws HeadlessException {
        cons = new GridBagConstraints();
        windowLayout = new BorderLayout();
        layout = new GridBagLayout();
        mainWindow = new JFrame();     
        mainPanel = new JPanel();

        mainWindow.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        init();
    }


    public void init()
    {
        mainWindow.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);

        mainWindow.setLayout(windowLayout);


        cons.ipadx = 5;
        cons.ipady = 5;
        cons.anchor = GridBagConstraints.NORTHWEST;
        cons.fill = GridBagConstraints.NONE;
        cons.weighty = 1.0;
        cons.weightx = 1.0;

        // to make everything work right we add a mainPanel under the mainWindow
        cons.gridheight = 1;
        cons.gridwidth = 1;

        mainWindow.add(mainPanel);
        // Readers keep in mind if you don't set this below, strange behavior happens
        mainPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        mainPanel.setLayout(layout);

        currentComponent = mainPanel;

        addLabel(0,0,"Character Name");
        characterName = addTextF(1,0,"",30,true);
        endRow(2,0);

        addButton(0,1,"Foo").addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e)
            {
                System.out.println(characterName.getText());
            }   
        });

        endVertical(0,2);

        mainWindow.setSize(1400, 900);

        mainWindow.setVisible(true);
    }

    /**
     * Inserts a spacer to signify the end of components for this row (effects layout so it doesn't center)
     */
    private void endRow(int x, int y)
    {
        cons.weightx = 100.0;
        addLabel(x,y,"");
        cons.weightx = 1.0;
    }

    /**
     * Inserts a spacer to signify the end of components vertically (effects layout so it doesn't center)
     */
    private void endVertical(int x, int y)
    { 
        cons.weighty = 100.0;
        addLabel(x,y,"");
        cons.weighty = 1.0;
    }

    /**
     * Shorthand command to add label at coordinates with text
     * @param x non-negative integer
     * @param y non-negative integer
     * @param text Display Text for label
     */
    private JLabel addLabel(int x, int y, String text)
    {
        JLabel temp = new JLabel(text);
        addC(temp,x,y);
        return temp;
    }

    /**
     * Shorthand command to add Button at coordinates with text
     * @param x non-negative integer
     * @param y non-negative integer
     * @param text Display Text for Button
     * @return The component created
     */
    private JButton addButton(int x, int y, String text)
    {
        JButton temp = new JButton(text);
        addC(temp,x,y);
        return temp;
    }

    /**
     * Shorthand command to add Text Field at coordinates with text
     * @param x non-negative integer
     * @param y non-negative integer
     * @param value the default value for the text field
     * @param cols Number of Columns
     * @param updateListen If true will add listener that triggers UI updates when values change
     * @return The component created
     */
    private JTextField addTextF(int x, int y, String value, int cols, boolean updateListen)
    {
        JTextField temp = new JTextField(value, cols);

        // this prevents the common issue of the text fields turning into slits
        temp.setMinimumSize(temp.getPreferredSize());

        addC(temp,x,y);
        return temp;
    }

    /**
     * Shorthand to add new components to the UI tab at given coords
     * @param comp Component to add to UI
     * @param x non-negative integer
     * @param y non-negative integer
     * 
     */
    private void addC(JComponent comp, int x, int y) {
        cons.gridx = x;
        cons.gridy = y;
        currentComponent.add(comp,cons);
    }


    /**
     * @param args
     */
    public static void main(String[] args) {

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                LifePathUI2 ui = new LifePathUI2();
                ui.init();
            }
        }); 

    }

}
我在这里搜索了所有的swing问题,没有一个问题与这个问题对应。我并不完全预料到这一点

我为这个更大的片段感到抱歉,但是由于所有的部分都是围绕着创建文本字段,阅读它们,创建GUI本身,所有这些似乎都与我在网上看到的示例相匹配。。。我很聪明,知道我在这里做了一些奇怪的事情,只是没有看到而已

编辑:简化示例。尽管将其分解为一个简单得多的测试用例,但仍然没有骰子
编辑2:完成了对内容的压缩。事实上,我希望它能够工作,因为这是我以前编写的工作代码的级别。但是仍然没有什么是胡乱猜测,但是您的
update()
方法看起来可能试图从其侦听的文档中提取文本(您没有说),如果是,则使用DocumentEvent获取文档,然后提取文本。比如:

private class TextChangeListener implements DocumentListener {
  @Override
  public void changedUpdate(DocumentEvent e) {
     update(e);
  }

  @Override
  public void insertUpdate(DocumentEvent e) {
     update(e);
  }

  @Override
  public void removeUpdate(DocumentEvent e) {
     update(e);
  }
}

除此之外,我对你的代码一无所知。简化重构。再简化一些。再重构一些。考虑可以单独进行完全测试的较小类


编辑

您调用了两次
init()
,这就是问题所在,因为这意味着您创建了所有内容中的两个,一个显示,一个不显示

你先在这里叫它:

public LifePathUI2() throws HeadlessException {
  // ....
  init();
}
然后在主菜单中再次调用:

  javax.swing.SwingUtilities.invokeLater(new Runnable() {
     public void run() {
        LifePathUI2 ui = new LifePathUI2();
        ui.init();
     }
  });
只调用它一次

更改此项:

public LifePathUI2() throws HeadlessException {
  cons = new GridBagConstraints();
  windowLayout = new BorderLayout();
  layout = new GridBagLayout();
  mainWindow = new JFrame();
  mainPanel = new JPanel();
  mainWindow.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  init();
}
为此:

public LifePathUI2() throws HeadlessException {
  cons = new GridBagConstraints();
  windowLayout = new BorderLayout();
  layout = new GridBagLayout();
  mainWindow = new JFrame();
  mainPanel = new JPanel();
  mainWindow.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  // init();
}

我无法理解为什么在所有不同的文本组件中,如果我在其中键入内容,getText()将始终返回“”
——这可能是因为您创建了两个组件,并且您的代码引用了一个未显示在框架中的组件,因此您得到了null。首先创建一个带有文本字段和按钮的简单框架。单击按钮时,将显示文本。向自己证明这个简单的案例是有效的。然后确定为什么有两个组件。你发布的代码太多,我看不清楚;您必须确保传递字符串。代码中的圈复杂度太高,这使得调试代码和发布小型可测试可运行程序变得困难。您应该重构代码以简化它,这样您就有了更小的类,这些类可以单独测试(通过适当的模拟),因为这将对您和我们现在以及将来都有帮助。@HoverCraftfullOfels-如果您看到具有textfield temp的Function getTextFVal(字符串名称),则不会使用文本设置它。。你觉得怎么样?@BhavikPatel:我正试图将他的代码精简到一个最小的形式,以了解它在做什么(他在发布之前应该为我们做的事情),但它仍然太复杂了。就是这样!谢谢我知道我已经从其他人的回答的评论中涵盖了大部分意外事件,但我总是错过这样的事情…@Vigilant:再次感谢你的简化,因为它帮了我很大的忙。
public LifePathUI2() throws HeadlessException {
  cons = new GridBagConstraints();
  windowLayout = new BorderLayout();
  layout = new GridBagLayout();
  mainWindow = new JFrame();
  mainPanel = new JPanel();
  mainWindow.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  // init();
}