AHora vamos a ver la clase principal llamada
EncuestaEsta clase es la que dibujará el marco principal, por lo tanto hereda de JFrame tal como ya hiciste en tu código.
Este marco irá apilando objetos de nuestra clase
Pregunta (recordemos que cada
Pregunta es un JPanel), uno encima de otro. Por lo tanto también usaremos un BoxLayout vertical para la organizacion visual.
El ultimo panel que tendrá abajo de todo, no será una
Pregunta sino un JPanel con los dos botones de "Enviar" y "Salir"
Para poder gestionar fácilmente las
Preguntas que vamos a crear, las debemos agrupar en algún tipo de colección, al menos en un arreglo, pero yo he preferido usar un ArrayList.
Al tenerlas todas agrupadas en una coleccion, luego mediante bucles podemos recorrer las Preguntas una a una para ir añadiendolas al marco principal, o para preguntarles que respuestas tienen marcadas cada una, o para lo que necesitemos...
Así que esta clase tan solo tendrá tres atributos: el ArrayList con los objetos
Pregunta y los dos botones JButton.
El constructor lo primero que hace es poner nombre al marco y justo después llama a un método que es el que se encarga de crear las Preguntas. Esto podría haberlo escrito directamente en el constructor, pero para que sea todo más legible, esta parte he preferido escribirla en un método separado.
Este método es muy sencillo, lo que hace es crear preguntas, con el enunciado deseado y los va añadiendo al ArrayList que se llama
listaPreguntasprivate void inicializarListaPreguntas() {
listaPreguntas.add(new Pregunta("1.¿Ha leído folletos informativos respecto a la Donación de Sangre?"));
listaPreguntas.add(new Pregunta("2.¿Ha donado sangre, plaquetas o plasma en los últimos 3 años?"));
/*
* Debido a la longitud de la pregunta 3, usamos codigo HTML dentro del JLabel para conseguir saltos de
* linea perfectamente centrados todo dentro de una unica etiqueta JLabel.
* Esto es gracias a que muchos componentes Swing soportan un HTML basico
*/
listaPreguntas.add(new Pregunta("<html><body><span align='center'>3.¿En los últimos 12 meses se ha realizado tatuajes, perforaciones,</span<br>"
+ "<span align='center'>acupuntura, transfusiones, cateterismos, endoscopias o ha tenido</span><br>"
+ "<span align='center'>contacto sexual con desconocidos?</span></body></html>"));
listaPreguntas.add(new Pregunta("4.¿Ha recibido algún transplante de órgano en los últimos 6 meses?"));
listaPreguntas.add(new Pregunta("5.¿Ha viajado en los últimos 28 dias a zonas con brotes epidemiológicos?"));
}
Una curiosidad es lo que ocurre con la pregunta numero 3. Su enunciado es mucho más largo que las de las otras preguntas. Si todo ese texto lo dejamos en una sola linea, nos deja una ventana un poco fea. Ya que es muy ancha para poder albergar toda esa linea, pero luego el resto de preguntas quedan un poco ridiculas con tan poco texto para tanta ventana.
Para evitar esto, lo ideal es añadir saltos de linea para partirla en tres lineas en lugar de solo una.
Pero, hay un problema. A un JLabel no puedes ponerle saltos de lineas -->
(\n)Se podría solventar usando tres JLabel en luga de uno, pero hemos diseñado nuestra clase
Pregunta para que solo tenga un JLabel y no vamos a diseñar una nueva clase especificamente para esta
Pregunta tan especial...
¿Como solucionarlo?
Pues con un truquito que a veces viene de maravilla para estas situaciones. Resulta que dentro del JLabel podemos usar codigo HTML a nivel básico, más que suficiente para crear saltos de linea y hacer que las tres lineas tengan el texto centrado.
Todo ello dentro de un único JLabel.
EL resto de preguntas no presentan problema, instanciamos un objeto
Pregunta, le pasamos el enunciado y lo añadimos al ArrayList.
Fíjate que fácil nos pone esto las cosas. Aquí podríamos hacer 10 preguntas, 50, 100, 5000....las que quisieramos... sin tener que declarar cientos de RadioButton y etiquetas JLabel especificas para cada pregunta que quisieramos poner en la encuesta.
Valiéndonos de las ventajas de la Programacion Orientada a Objetos (POO), simplemente hemos necesitado diseñar una sencilla clase llamada
Pregunta y ahora podemos replicarla tantas veces como queramos y gestionarlas fácilmente desde un ArrayList.
Una vez inicialiadas las
Preguntas, ya cada una con su propio enunciado.
Inicializamos los botones send y salir. Les ponemos un texto, una fuente a nuestro gusto y les añadimos un ActionListener para indicarles que ha de hacer cada boton.
send = new JButton("Enviar");
send.setFont(new Font("Berlin Sans FB", Font.PLAIN, 14));
send.addActionListener(new AccionEnviar());
salir = new JButton("Salir");
salir.setFont(new Font("Berlin Sans FB", Font.PLAIN, 14));
salir.addActionListener(new AccionSalir());
De nuevo, para no hacer un código de dificil lectura, las acciones de los ActionListener las he declarado como clases separadas. Así el constructor no está saturado de lineas de código.
Estas clases están declaradas dentro de la propia clase
Encuesta (es lo que se llama anidar clases) y tienen el siguiente codigo.
La del boton salir es fácil, ocultar el marco y dar orden de eliminarlo con dispose()
class AccionSalir implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
setVisible(false);
dispose();
}
}
La del boton enviar tampoco es complicada.
Eso sí, se supone que este boton ha de escribir las respuestas en un fichero de texto. Esto de momento no lo he hecho. Primero centrémonos en que nos quede claro como hemos creado y organizado la encuesta, y luego nos ponemos con como queremos escribir la informacion en el archivo texto.
Esta clase lo que hace es recorrer las Preguntas una a una (bendito ArrayList) pregunta que respuesta hay marcada y las va juntando en unico String que luego mostraremos en un ventana pop-up.
Además comprueba si alguna de las
Preguntas responde con un null.
Esto significa que el usuario se ha olvidado de marcar alguna respuesta. En este caso, lo que le mostramos al usuario es una advertencia indicandole su olvido.
Para saber que respuesta hay marcada, usamos el método
getRespuesta() que habíamos creado en la clase
Preguntaclass AccionEnviar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String respuestas = "";
boolean todasContestadas = true;
for (int i = 0; i < listaPreguntas.size(); i++) {
if (listaPreguntas.get(i).getRespuesta() == null) {
JOptionPane.showMessageDialog(null, "Por Favor, conteste todas las preguntas",
"Preguntas sin respuesta", JOptionPane.WARNING_MESSAGE);
todasContestadas = false;
break;//Dejamos de obtener respuestas.
}
else {
respuestas += (i+1) + " --> " + listaPreguntas.get(i).getRespuesta() + "\n";
}
}
//Mostramos respuestas, si es que las tenemos todas
if (todasContestadas)
JOptionPane.showMessageDialog(null, respuestas, "Respuestas", JOptionPane.INFORMATION_MESSAGE);
}
}
Y bueno, ya tenemos las preguntas inicializadas y también los botones, con sus acciones ya establecidas.
Ahora hay que indicarle al JFrame que layout deseamos:
setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
Fijate que aquí al constructor del BoxLayout usamos el metodo getContentPane()
En la clase Pregunta nos bastaba con usar la palabra reservada
this. Esto es porque
Pregunta hereda de JPanel, pero
Encuesta hereda de JFrame
Al crear un gestor BoxLayout() hay que pasarle dos parametros, el primero indicarle que contenedor ha de gestionar y segundo la orientacion (vertical u horizontal)
Cuando se trata de una JPanel, estamos tratando explicitamente con un contenedor así que nos basta con referirnos a él con
thisPero cuando tratamos con un JFrame, estamos tratando con un marco, no directamente con su contenedor.. así que tenemos que solicitarle su contenedor con el metodo getContentPane() para que el BoxLayout sepa qué es lo que tiene que gestionar.
Establecido el layout, añadimos las
Preguntas que ya están inicializadas. De nuevo gracias al ArrayList, lo hacemos fácilmente con un bucle
for (Pregunta pregun: listaPreguntas)
add(pregun);
Tras las preguntas, creamos un último JPanel para los botones. Para que los botones queden centrados, dejamos el FlowLayout que viene por defecto.
Añadimos lo botones al JPanel, y este JPanel al marco, donde quedará por debajo de las preguntas.
JPanel panelBotones = new JPanel();
panelBotones.add(send);
panelBotones.add(salir);
add(panelBotones);
Y ya por último, al marco JFrame hay que darle unas últimas indicaciones. Los comentarios lo explican
pack();//Automaticamente se organizan todos los componentes dentro del marco
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Cerrar al pulsar la pestaña superior de cierre.
setResizable(false);//Evitamos que las dimensiones del marco sean manipulables por el usuario
setLocationRelativeTo(null);//El marco aparecerá justo en el centro de la pantalla
setVisible(true);//Hacemos el marco visible
Y con esto ya tenemos el marco listo.
Solo hace falta ponerlo en marcha. Para ello, a nuestra clase Encuesta le añadimos un metodo main() que se encargue de instanciarla.
public static void main(String[] args) {
new Encuesta();
}
Todo esto nos da un formulario muy simple, pero que funciona perfectamente.

Ahora aquí te pongo el código completo de la clase
Encuesta.
Ya solo quedaría hablar de como queremos que los datos se graben en un archivo de texto. Pero antes, asegurate de que todo lo que hemos hecho te ha quedado más o menos claro, así que pregunta todo lo que no entiendas, prueba tu a modificar cosas para ver como se comporta, haz lo que sea necesario para entenderlo.
Un saludo.
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public final class Encuesta extends JFrame{
private ArrayList<Pregunta> listaPreguntas = new ArrayList<Pregunta>();
private JButton send, salir;
public Encuesta(){
super("Encuesta");
//Inicializamos componentes
inicializarListaPreguntas();
send = new JButton("Enviar");
send.setFont(new Font("Berlin Sans FB", Font.PLAIN, 14));
send.addActionListener(new AccionEnviar());
salir = new JButton("Salir");
salir.setFont(new Font("Berlin Sans FB", Font.PLAIN, 14));
salir.addActionListener(new AccionSalir());
/*
* Organizamos layout del marco.
* Usaremos un BoxLayout vertical donde se irán apilando las preguntas
* una encima de otra.
* Al final añadiremos un ultimo Jpanel con los dos JButton
*/
setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
//Agregamos la preguntas. Recorremos el ArrayList y añadimos una a una
for (Pregunta pregun: listaPreguntas)
add(pregun);
//Finalmente, un JPanel con los botones. Este Jpanel usará el FLowLayout por defecto
JPanel panelBotones = new JPanel();
panelBotones.add(send);
panelBotones.add(salir);
add(panelBotones);
//Definimos comportamiendo del marco
pack();//Automaticamente se organizan todos los componentes dentro del marco
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Cerrar al pulsar la pestaña superior de cierre.
setResizable(false);//Evitamos que las dimensiones del marco sean manipulables por el usuario
setLocationRelativeTo(null);//El marco aparecerá justo en el centro de la pantalla
setVisible(true);//Hacemos el marco visible
}
class AccionSalir implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
setVisible(false);
dispose();
}
}
class AccionEnviar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String respuestas = "";
boolean todasContestadas = true;
for (int i = 0; i < listaPreguntas.size(); i++) {
if (listaPreguntas.get(i).getRespuesta() == null) {
JOptionPane.showMessageDialog(null, "Por Favor, conteste todas las preguntas",
"Preguntas sin respuesta", JOptionPane.WARNING_MESSAGE);
todasContestadas = false;
break;//Dejamos de obtener respuestas.
}
else {
respuestas += (i+1) + " --> " + listaPreguntas.get(i).getRespuesta() + "\n";
}
}
//Mostramos respuestas, si es que las tenemos todas
if (todasContestadas)
JOptionPane.showMessageDialog(null, respuestas, "Respuestas", JOptionPane.INFORMATION_MESSAGE);
}
}
/**
* Inicializa el arrayList con los objetos de la clase Pregunta
*/
private void inicializarListaPreguntas() {
listaPreguntas.add(new Pregunta("1.¿Ha leído folletos informativos respecto a la Donación de Sangre?"));
listaPreguntas.add(new Pregunta("2.¿Ha donado sangre, plaquetas o plasma en los últimos 3 años?"));
/*
* Debido a la longitud de la pregunta 3, usamos codigo HTML dentro del JLabel para conseguir saltos de
* linea perfectamente centrados todo dentro de una unica etiqueta JLabel.
* Esto es gracias a que muchos componentes Swing soportan un HTML basico
*/
listaPreguntas.add(new Pregunta("<html><body><span align='center'>3.¿En los últimos 12 meses se ha realizado tatuajes, perforaciones,</span<br>"
+ "<span align='center'>acupuntura, transfusiones, cateterismos, endoscopias o ha tenido</span><br>"
+ "<span align='center'>contacto sexual con desconocidos?</span></body></html>"));
listaPreguntas.add(new Pregunta("4.¿Ha recibido algún transplante de órgano en los últimos 6 meses?"));
listaPreguntas.add(new Pregunta("5.¿Ha viajado en los últimos 28 dias a zonas con brotes epidemiológicos?"));
}
public static void main(String[] args) {
new Encuesta();
}
}