在 JPanel 中显示 JPanel 数组

Displaying an array of JPanels in a JPanel

我对 Swing 有点陌生,我一直在尝试在 JPanel 中显示 JPanel 数组时遇到问题。

该程序根据用户输入的信息将 Student 对象添加到 Driver class 中的数组列表,然后应该在 studentPane JPanel 中的单独 JPanel 上显示该信息,但它们从未显示信息输入后

我尝试的第一件事是通过创建一个名为 getInfoPane 的方法让 Student class return 成为一个 JPanel,该方法 return 是在学生 class 中创建的一个 JPanel所有必要的信息,然后调用:

studentPane.add(students.get(x).getInfoPane());

但这没有用。我还尝试让 Student class 扩展 JPanel,将学生的信息添加到该面板,然后尝试将其添加到驱动程序 class 中的 studentPane JPanel,但两者都不显示。

目前,我正在尝试使用一个名为 StudentInfo 的单独的 JPanel 数组列表,并使用以下代码添加学生:

for(int x=0; x<Integer.parseInt(numberField.getText()); x++) { 
     studentInfo.add(new JPanel ());    //add new JPanel to array
     studentInfo.get(x).add(new JLabel (students.get(x).toString()));  //add info from Student
     studentPane.add(studentInfo.get(x));  //add JPanel with student info to main Student JPanel
}

toString 方法被覆盖为 return 一个字符串,其中包含输入到学生 class 的信息。这个方法也没有用。我已经检查以确保 Student class 正在接收输入的信息,并且打印出来的信息正常。我也尝试过直接将组件(如 JLabel)添加到 Driver class 中的 studentPane,但是它不起作用。经过一些测试后,我发现字符串是唯一会出现在 studentPane 上的东西。这让我认为问题处理的不是从另一个 class 传递 JPanel 以外的事情。我已经查看了许多具有类似问题的其他问题,但无法使解决方案适用于我的程序。

到目前为止,这是我程序中的相关代码:

public class Driver extends JFrame {

     private Container contentPane;
     ArrayList<Student> students = new ArrayList<Student>();
     private JPanel studentPane = new JPanel();
     ArrayList<JPanel> studentInfo = new ArrayList<JPanel>();

     public static void main(String[] args) {
          EventQueue.invokeLater(new Runnable() {
               public void run() {
                    try {
                         Driver frame = new Driver();
                         frame.setVisible(true);
                    } catch (Exception e) {
                         e.printStackTrace();
                    }
               }
           });
     }

     public Driver() {
          contentPane = this.getContentPane();

          profiles.add(addStudentProfiles);         // this chunk has the user input student info and tries to add it to studentPane
          addStudentProfiles.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent e) {      
                    JOptionPane.showMessageDialog(null, number, "Number to create", JOptionPane.INFORMATION_MESSAGE );
                    if(numberField.getValue() != null) {
                         for(int x=0; x<Integer.parseInt(numberField.getText()); x++) {
                              while(nameField.getText().equals("") || workEthicField.getText().equals("")) {
                                   JOptionPane.showMessageDialog(null, studentInputs, "New Student", JOptionPane.PLAIN_MESSAGE);
                                   if(nameField.getText().equals("") || workEthicField.getText().equals("")) 
                                        JOptionPane.showMessageDialog(null, "Error. Please fill out all of the fields");
                              }
                              students.add(new Student(nameField.getText(), Integer.parseInt(workEthicField.getText()), (String)(major1Field.getSelectedItem())));
                              nameField.setText(""); workEthicField.setValue(null);
                         }
                         for(int x=0; x<Integer.parseInt(numberField.getText()); x++) {
                              studentInfo.add(new JPanel ());
                              studentInfo.get(x).add(new JLabel (students.get(x).toString()));
                              studentPane.add(studentInfo.get(x));
                         }
                         numberField.setValue(null);
                    }
               }
          });

          setContentPane(contentPane);
          contentPane.setLayout(null);

          studentPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createMatteBorder(3, 3, 3, 3, Color.black), "Students", TitledBorder.CENTER, TitledBorder.CENTER));
          studentPane.setLocation(350, 0);
          studentPane.setSize(300, (int)getBounds().getHeight()-62);
          studentPane.setBackground(Color.lightGray);
          studentPane.setVisible(true);
          contentPane.add(studentPane);
     }
}

这是学生 class:

public class Student {

     private String name, major;
     private int workEthic;
     private String info = "";

     public Student(String name, int workEthic, String major) {

          this.name = name;
          this.workEthic = workEthic;
          this.major = major;

          info = name+ "\n" +major+ "\n" +workEthic;
     }

     public String toString() {
          return info;
     }
}

所以基本上,我只是想知道为什么程序不会在 studentPane JPanel(位于整个 contentPane 容器内)中显示 JPanel(或组件),以及这样做的正确方法是什么.任何帮助将不胜感激,因为我已经被困在这个问题上一段时间了。

不要在您的内容窗格中使用空布局。让内容窗格包含框架可用的所有 space。

I found that strings were the only thing that would show up on the studentPane.

这种说法完全没有道理。字符串不是组件,不能添加到 JPanel。您的代码当前添加了一个包含面板的 toString() 表示形式的 JLabel。

将组件动态添加到可见 GUI 的通用代码是:

panel.add(...);
panel.revalidate(); // invoke layout manager
panel.repaint(); paint all components

默认情况下,组件的大小为 (0, 0),因此在您调用布局管理器之前,没有什么可绘制的。