Es normal bloquearse al principio

Y también seguir caminos que llevan a callejones sin salida, pero no te preocupes, forma parte del proceso de aprendizaje.
Lo ideal es centrarte primero en crear la Vista, sin preocuparte demasiado por el Modelo.
Es decir, haz una interfaz con sus campos y botones, que de momento, no van a tener ninguna función.
Luego ya irás integrando el Modelo. Y sí, puede que durante ese proceso veas la necesidad de reescribir o desechar parte del código escrito para la Vista. Pero así va esto.
A ver, voy a empezar un proyecto de cero.
En el diseño que propones, tanto para la parte de arriba como para la de abajo, yo crearía dos paneles a partir de una única clase.
Lo señalado en rojo serían dos paneles, pero de una misma clase.
Y lo mismo para lo señalado en verde.

Veamos la clase para los paneles superiores.
En lo que respecta a la Vista, entre ambos paneles solo cambia el titulo del borde del panel y las opciones del JComboBox. Así que estos datos se pueden indicar por el constructor
Para maquetar los componentes, puedes usar el/los layouts que tú prefieras.
Yo (de momento) creo que voy a usar un BoxLayout vertical, donde apilar paneles unos sobre otros.
Estos paneles los haré con una subclase que reciba por constructor el texto para un JLabel y el componente que acompañará
Clase
PanelCrearSoldadopublic class PanelCrearSoldado extends JPanel {
private JTextField jtNombre;
private JComboBox<String> jcTipo;
private JTextField jtVida;
private JTextField jtArmadura;
private JButton btAnadir;
public PanelCrearSoldado(String titulo, String[] tipos) {
//Inicializamos componentes
jtNombre = new JTextField();
jcTipo = new JComboBox<String>(tipos);
jtVida = new JTextField();
jtArmadura = new JTextField();
btAnadir = new JButton("Añadir");
//Layout de "cajas" verticales
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
/*
* Cada "caja" apilada verticalmente será un panel
* de clase PanelConLabel
*/
add(new PanelConLabel("Nombre:", jtNombre));
add(new PanelConLabel("Tipo:", jcTipo));
add(new PanelConLabel("Vida:", jtVida));
add(new PanelConLabel("Armadura:", jtArmadura));
//Boton añadir
add(btAnadir);
//Combinamos dos bordes, uno titulado y otro vacío para crear algo de relleno
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(15, 15, 15, 15),
BorderFactory.createTitledBorder(titulo)));
}
private class PanelConLabel extends JPanel {
public PanelConLabel(String texto, JComponent componente) {
//Layout tipo grilla, será una fila con dos columnas
setLayout(new GridLayout(1,2));
//En la primera columna, la etiqueta
add(new JLabel(texto));
//En la segunda columna, el componente que acompaña la etiqueta
add(componente);
}
}
}
Estaría bien poder ver cómo ha quedado, así que vamos a crear ahora la clase principal, que será el JFrame que contenga toda la interfaz.
De momento mostraremos solo el panel que hemos desarrollado, a ver que aspecto tiene.
public class BatallaRPG extends JFrame {
private PanelCrearSoldado crearHeroes;
public BatallaRPG() {
crearHeroes = new PanelCrearSoldado("Heroes", new String[] {"Elfo", "Humano", "Hobbit"});
setContentPane(crearHeroes);
setTitle("Batalla RPG");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new BatallaRPG();
}
});
}
}
Veamos qué se nos dibuja en pantalla:

Bueno, no es una belleza, pero básicamente es el diseño que buscábamos. Necesita arreglillos.
Más separación entre las "cajas" apiladas, podemos hacerlo inflándolas un poco añadiendo algo de borde vacío en su interior.
Y el botón "Añadir" quedará mejor centrado si lo colocamos dentro de su propio panel...
public class PanelCrearSoldado extends JPanel {
private JTextField jtNombre;
private JComboBox<String> jcTipo;
private JTextField jtVida;
private JTextField jtArmadura;
private JButton btAnadir;
public PanelCrearSoldado(String titulo, String[] tipos) {
//Inicializamos componentes
jtNombre = new JTextField();
jcTipo = new JComboBox<String>(tipos);
jtVida = new JTextField();
jtArmadura = new JTextField();
btAnadir = new JButton("Añadir");
//Layout de "cajas" verticales
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
/*
* Cada "caja" apilada verticalmente será un panel
* de clase PanelConLabel
*/
add(new PanelConLabel("Nombre:", jtNombre));
add(new PanelConLabel("Tipo:", jcTipo));
add(new PanelConLabel("Vida:", jtVida));
add(new PanelConLabel("Armadura:", jtArmadura));
//Boton añadir, le damos un panel propio para que quede mejor centrado
JPanel pnAnadir = new JPanel();
pnAnadir.add(btAnadir);
add(pnAnadir);
//Combinamos dos bordes, uno titulado y otro vacío para crear algo de relleno
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(15, 15, 15, 15),
BorderFactory.createTitledBorder(titulo)));
}
private class PanelConLabel extends JPanel {
public PanelConLabel(String texto, JComponent componente) {
//Layout tipo grilla, será una fila con dos columnas
setLayout(new GridLayout(1,2));
//En la primera columna, la etiqueta
add(new JLabel(texto));
//En la segunda columna, el componente que acompaña la etiqueta
add(componente);
//"Inflamos" el panel con algo de borde vacío
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
}
}
A ver...

Bueno, ya tiene mejor aspecto. Por ahora puede servir para seguir avanzando.
Lo que haremos será poner a su lado un segundo panel, esta vez para crear Bestias.
Para ponerlos juntos, en el JFrame crearemos un "panel superior" donde insertaremos nuestros dos paneles de creación de soldados.
public class BatallaRPG extends JFrame {
private PanelCrearSoldado crearHeroes;
private PanelCrearSoldado crearBestias;
public BatallaRPG() {
crearHeroes = new PanelCrearSoldado("Heroes", new String[] {"Elfo", "Humano", "Hobbit"});
crearBestias = new PanelCrearSoldado("Bestias", new String[] {"Trasgo", "Orco"});
JPanel pnSuperior = new JPanel();
pnSuperior.add(crearHeroes);
pnSuperior.add(crearBestias);
setContentPane(pnSuperior);
setTitle("Batalla RPG");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new BatallaRPG();
}
});
}
}
Y de esta manera, con una única clase JPanel, ya tenemos dos paneles idénticos para crear un tipo de soldado u otro.

Bueno, y ahora viene el quid de la cuestión.
¿Dónde se guardan los soldados? ¿Cómo sabrán estos paneles que soldado crear y donde ubicarlos?
Bien, tendremos dos Ejercitos, y estos conviene que se encuentren en la clase principal JFrame, para que su "ámbito" sea lo más amplio posible y los distintos paneles que finalmente compongan la interfaz tengan posibilidad de acceder a ellos.
Así que los añadimos como atributos del JFrame, y los inicializamos en el constructor.
public class BatallaRPG extends JFrame {
//Modelo
private Ejercito bestias;
private Ejercito heroes;
//Vista
private PanelCrearSoldado crearHeroes;
private PanelCrearSoldado crearBestias;
public BatallaRPG() {
bestias = new Ejercito();
heroes = new Ejercito();
crearHeroes = new PanelCrearSoldado("Heroes", new String[] {"Elfo", "Humano", "Hobbit"});
crearBestias = new PanelCrearSoldado("Bestias", new String[] {"Trasgo", "Orco"});
JPanel pnSuperior = new JPanel();
pnSuperior.add(crearHeroes);
pnSuperior.add(crearBestias);
setContentPane(pnSuperior);
setTitle("Batalla RPG");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new BatallaRPG();
}
});
}
}
Ahora necesitamos que los paneles de creación de soldados, tengan algún tipo de conexión con estos ejércitos para poder agregarles soldados.
Una forma, sería dotar a estos paneles de una referencia a estos ejércitos. Como cada panel va a interactuar con un único ejercito, le añadimos a su clase un ejercito como atributo, y recibirá por constructor la referencia de uno de los ejércitos declarados en la clase principal.
Ya de paso, desarrollamos un ActionListener para que el botón "Añadir" comience a funcionar.
Esta acción ha de recuperar los datos de los campos, evaluar que tipo de soldado se está creando y añadirlo al ejercito que tenga referenciado.
De momento, podemos informar por consola de que hay un nuevo recluta.
public class PanelCrearSoldado extends JPanel {
private JTextField jtNombre;
private JComboBox<String> jcTipo;
private JTextField jtVida;
private JTextField jtArmadura;
private JButton btAnadir;
//Atributo para referenciar alguno de los ejercitos de la clase main
private Ejercito ejercito;
public PanelCrearSoldado(String titulo, String[] tipos, Ejercito ejercito) {
//Inicializamos componentes
jtNombre = new JTextField();
jcTipo = new JComboBox<String>(tipos);
jtVida = new JTextField();
jtArmadura = new JTextField();
btAnadir = new JButton("Añadir");
btAnadir.addActionListener(new AccionCrearSoldado());
this.ejercito = ejercito; //Ejercito referenciado
//Layout de "cajas" verticales
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
/*
* Cada "caja" apilada verticalmente será un panel
* de clase PanelConLabel
*/
add(new PanelConLabel("Nombre:", jtNombre));
add(new PanelConLabel("Tipo:", jcTipo));
add(new PanelConLabel("Vida:", jtVida));
add(new PanelConLabel("Armadura:", jtArmadura));
//Boton añadir, le damos un panel propio para que quede mejor centrado
JPanel pnAnadir = new JPanel();
pnAnadir.add(btAnadir);
add(pnAnadir);
//Combinamos dos bordes, uno titulado y otro vacío para crear algo de relleno
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(15, 15, 15, 15),
BorderFactory.createTitledBorder(titulo)));
}
private class PanelConLabel extends JPanel {
public PanelConLabel(String texto, JComponent componente) {
//Layout tipo grilla, será una fila con dos columnas
setLayout(new GridLayout(1,2));
//En la primera columna, la etiqueta
add(new JLabel(texto));
//En la segunda columna, el componente que acompaña la etiqueta
add(componente);
//"Inflamos" el panel con algo de borde vacío
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
}
private class AccionCrearSoldado implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//Recogemos datos
String nombre = jtNombre.getText();
String tipo = (String) jcTipo.getSelectedItem();
int vida = Integer.parseInt(jtVida.getText());
int armadura = Integer.parseInt(jtArmadura.getText());
//Creamos nuevo soldado según tipo
switch(tipo) {
case "Elfo":
ejercito.reclutarSoldado(new Elfos(nombre, vida, armadura));
break;
case "Humano":
ejercito.reclutarSoldado(new Humano(nombre, vida, armadura));
break;
case "Hobbit":
ejercito.reclutarSoldado(new Hobbits(nombre, vida, armadura));
break;
case "Trasgo":
ejercito.reclutarSoldado(new Trasgo(nombre, vida, armadura));
break;
case "Orco":
ejercito.reclutarSoldado(new Orcos(nombre, vida, armadura));
break;
}
//Limpiamos campos
jtNombre.setText(null);
jcTipo.setSelectedIndex(0);
jtVida.setText(null);
jtArmadura.setText(null);
//Confirmamos en consola la creación
System.out.println("Nuevo soldado reclutado");
}
}
}
Ahora en la clase JFrame, ya podemos pasarles las referencias a estos paneles
public class BatallaRPG extends JFrame {
//Modelo
private Ejercito bestias;
private Ejercito heroes;
//Vista
private PanelCrearSoldado crearHeroes;
private PanelCrearSoldado crearBestias;
public BatallaRPG() {
bestias = new Ejercito();
heroes = new Ejercito();
//Este panel referenciará los Heroes
crearHeroes = new PanelCrearSoldado("Heroes", new String[] {"Elfo", "Humano", "Hobbit"}, heroes);
//Este refenciará a la Bestias
crearBestias = new PanelCrearSoldado("Bestias", new String[] {"Trasgo", "Orco"}, bestias);
Y ahora ya podemos crear soldados en los ejércitos.
Parece que todo va por buen camino, pero luego va a venir una dificultad....

Los soldados creados, han de mostrarse en un JList que aún no hemos creado. Este JList, se escribirá en otra clase JPanel.
La idea es que, al pulsar el botón "Añadir" en el panel de creación, se muestre el nuevo soldado en el JList.
Pero, y he aquí la dificultad, el botón "Añadir" y el JList pertenecen a clases diferentes. Desde el ActionListener que hemos escrito en el panel de crear personajes, no podemos actuar sobre el JList. Habrá que buscar, de nuevo, alguna solución para que haya comunicación entre esos paneles.
Pero eso ya lo veremos luego.