Fala, Robertdm!
Bom, o post vai ficar muito grande se eu for encher de exemplos, então vamos diretamente ao que você quer.
Qual é o lance de criar os componentes dinamicamente? É possuir uma coleção dos dados que eu quero adicionar e iterar sobre esta coleção!
Por exemplo, suponhamos que eu tenha vários Tipos de Documentos e cada um desses tipos possui vários campos relativos a ele. Se eu iterar sobre esses tipos de documentos, eu trago os campos que cada um possui e adiciono em um painel específico.
Bom, vou fazer um exemplo de como você pode fazer esse lance com os alunos:
Usando o MigLayout…
public class AlunosForm extends JFrame
{
   private List<Aluno> alunos;
   
   // Perceba que o construtor receberá uma lista de alunos.
   // Estes serão os alunos sobre os quais iteraremos. (gostei dessa palavra xD)
   public AlunosForm(List<Aluno> alunos)
   {
      super( ".: Adicionando Componentes Dinamicamente :.");
      this.alunos = alunos != null ? alunos : new ArrayList<Aluno>();
      initingComponents();
   }
   private void initingComponents()
   {
      Container container = getContentPane();
      container.setLayout( new MigLayout() );
      // Para cada aluno que temos na coleção...
      for (Aluno aluno : alunos) {
     
         //construímos um JPanel específico para ele.
         container.add( getAlunoPanel( aluno ), "wrap");
      }
   }
   private JPanel getAlunoPanel( Aluno aluno )
   {
      JPanel panel = new JPanel( new MigLayout() );
      JLabel label; 
      
      label = new JLabel( "Aluno: " + aluno.getNome() );
      label.setFont( new Font("Tahoma", 1, 16) );
      panel.add( label, "wrap 20" );
      label = new JLabel("Valor da Mensalidade:");
      panel.add( label, "align right" );
      JTextField text = new JTextField( 20, aluno.getMensalidade() );
      panel.add( text, "align left, wrap" );
      // E assim 'substantivamente', como diria o célebre Seu Madruga.
   }
}
E agora, usando o GridBagLayout:
public class AlunosForm extends JFrame
{
   private List<Aluno> alunos;
   
   // Perceba que o construtor receberá uma lista de alunos.
   // Estes serão os alunos sobre os quais iteraremos. (gostei dessa palavra xD)
   public AlunosForm(List<Aluno> alunos)
   {
      super( ".: Adicionando Componentes Dinamicamente :.");
      this.alunos = alunos != null ? alunos : new ArrayList<Aluno>();
      initingComponents();
   }
   private void initingComponents()
   {
      Container container = getContentPane();
      container.setLayout( new GridBagLayout() );
      GridBagConstraints cc = new GridBagConstraints();
      cc.insets = new Insets( 5, 5, 5, 5 );
      cc.gridx = 0; cc.gridy = 0;
      // Para cada aluno que temos na coleção...
      for (Aluno aluno : alunos) {
     
         //construímos um JPanel específico para ele.
         container.add( getAlunoPanel( aluno ), cc);
         cc.gridx++;
      }
   }
   private JPanel getAlunoPanel( Aluno aluno )
   {
      JPanel panel = new JPanel( new GridBagLayout() );
      GridBagConstraints cc = new GridBagConstraints();
      JLabel label; 
      cc.insets = new Insets( 5, 5, 5, 5 );
      cc.gridx = 0; cc.gridy = 0;
      
      label = new JLabel( "Aluno: " + aluno.getNome() );
      label.setFont( new Font("Tahoma", 1, 16) );
      panel.add( label, cc );
      cc.gridx++;
      cc.anchor = GridBagConstraints.RIGHT;
      label = new JLabel("Valor da Mensalidade:");
      panel.add( label,  cc);
      cc.gridy++;
      cc.anchor = GridBagConstraints.LEFT;
      JTextField text = new JTextField( 20, aluno.getMensalidade() );
      panel.add( text, cc );
      cc.gridx++; cc.gridy = 0;
      // E assim 'substantivamente', como diria o célebre Seu Madruga.
   }
}
Deu pra ter uma ideia legal de como funciona?
Abraços!