Java 无法添加动态jtextfields并保存其值

Java 无法添加动态jtextfields并保存其值,java,swing,Java,Swing,在previos我的问题中,我问了类似的问题。但是在我以前的项目中,我使用了GUI builder,所以现在我想在没有builder的情况下动态地将JTextField添加到面板中。我不知道为什么,但出于某种原因,我无法执行此代码: public class Reference { JFrame frame = new JFrame(); JPanel MainPanel = new JPanel(); MainPanel main = new MainPanel();

在previos我的问题中,我问了类似的问题。但是在我以前的项目中,我使用了GUI builder,所以现在我想在没有builder的情况下动态地将
JTextField
添加到
面板中。我不知道为什么,但出于某种原因,我无法执行此代码:

public class Reference {
    JFrame frame = new JFrame();
    JPanel MainPanel = new JPanel();
    MainPanel main = new MainPanel();
    JPanel SubPanel = new JPanel();
    JButton addButton = new JButton();
    JButton saveButton = new JButton();
    private List<JTextField> listTf = new ArrayList<JTextField>();
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       new Reference();
    }

    public Reference() {
        frame.add(main);
        frame.setLayout(new BorderLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(addButton, BorderLayout.EAST);
        frame.add(saveButton, BorderLayout.WEST);
        frame.pack();
        frame.setSize(500, 300); 
        frame.setVisible(true);
        main.setLayout(new BorderLayout()); 
        main.setBackground(Color.green);                 
        main.add(SubPanel);
        SubPanel.setBackground(Color.yellow);

        addButton.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent evt) {
                    main.add(new SubPanel());
                    main.revalidate();
                }
            }); 

        saveButton.addActionListener(new ActionListener(){

                public void actionPerformed(ActionEvent evt) {
                    for (int i = 0; i < main.getComponentCount();) {
                SubPanel panel = (SubPanel)main.getComponent(i);
                JTextField firstName = panel.getFirstName();
                String text = firstName.getText();
                System.out.println( text );
  }}
      });

    }

    private class SubPanel extends JPanel {   

       JTextField firstName = new JTextField(15);

    public SubPanel() {

            this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
            this.add(firstName);
      listTf.add(firstName);
        }
    public JTextField getFirstName()
{
    return firstName;
}
    } 


  public class MainPanel extends JPanel
{
    List<SubPanel> subPanels = new ArrayList<SubPanel>();

    public MainPanel()
    {
    }

    public void addSubPanel()
    {
        SubPanel panel = new SubPanel();
        add(panel);
        subPanels.add(panel);
    }

   public SubPanel getSubPanel(int index)
    {
        return subPanels.get(index);
    }
  }
}
公共类参考{
JFrame=新JFrame();
JPanel MainPanel=新的JPanel();
主面板main=新的主面板();
JPanel SubPanel=新的JPanel();
JButton addButton=新JButton();
JButton saveButton=新JButton();
private List listf=new ArrayList();
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
新引用();
}
公众参考(){
帧。添加(主);
frame.setLayout(新的BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(addButton,BorderLayout.EAST);
frame.add(saveButton,BorderLayout.WEST);
frame.pack();
框架。设置尺寸(500300);
frame.setVisible(true);
main.setLayout(新的BorderLayout());
主.背景(颜色.绿色);
主。添加(子面板);
亚板挫折背景(颜色:黄色);
addButton.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件evt){
main.add(新的子面板());
main.revalidate();
}
}); 
saveButton.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件evt){
对于(int i=0;i
并通过
saveButton
尝试获取
JTextField
的值,但没有成功。在输出中,我只能看到带有2个按钮的
JFrame
,但是
addButton
saveButton
ActionListener
未激活。我不明白哪里错了


任何帮助都将不胜感激。

在Swing中,您做某些事情的顺序非常重要,例如

frame.add(main);
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(addButton, BorderLayout.EAST);
frame.add(saveButton, BorderLayout.WEST);
frame.pack();
frame.setSize(500, 300); 
frame.setVisible(true);
  • 您将
    main
    添加到
    框架中
  • 您可以设置框架布局(!?)
  • 你加上你的按钮
  • 你把镜框打包
  • 您设置了它的大小(!?)
  • 你让它可见
  • 这里的问题是第二步。相反,如果我们只是删除步骤2(步骤4和步骤5也不太好),您会发现您的窗口现在包含
    main

    frame.add(main);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(addButton, BorderLayout.EAST);
    frame.add(saveButton, BorderLayout.WEST);
    frame.pack();
    frame.setVisible(true);
    
    这个

    for (int i = 0; i < main.getComponentCount();) {
        SubPanel panel = (SubPanel) main.getComponent(i);
    
    for(int i=0;i
    一个坏主意有三个原因

  • 您的循环永远不会前进(
    i
    将始终是
    0
  • 你是在盲目地铸造
    main
    的内容,却不知道上面有什么
  • 主面板
    已经有一个
    子面板的
    列表

  • 您需要确保通过
    addSubPanel
    方法添加
    SubPanel
    (这可能会返回
    SubPanel
    的一个实例),并提供一种方法,您可以通过某种
    getter
    访问此
    列表(即文本字段text)而不是
    子面板本身;)

    您可以从不执行此操作开始->
    子面板=(子面板)main.getComponent(i);
    for(int i=0;i
    。您盲目地强制转换组件而不知道它们是什么,并且您的
    for loop
    将永远只比较第一个组件……您将需要引用
    Main
    子面板,这就是为什么我建议您需要另一个getter在MainPanel中编写一个getter,返回子面板列表a然后用它来提取你想要的细节