Questionnaire

/**
 * Clase Questionnaire -> Christian Sarmiento
 */

//Se importan las librerías necesarias para el midlet que se le envía y
//los componentes gráficos
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

//Se importa la librería necesaria para manejar vectores
//(listas usadas como arreglos dinámicos)
import java.util.*;

/**
 * @author Christian Sarmiento
 */

public class Questionnaire extends Form implements CommandListener{

    //----------------------Atributos de la clase-----------------------------\\
    private String name;   //Identificador del cuestionario
    private String fileLocation;   //Ruta del archivo de texto
    private int numberOfQuestions;   //Numero de preguntas en el cuestionario
    private int numberOfCorrectAnswers;   //Numero de respuestas correctas
    private MIDlet theMidlet;   //El midlet desde donde se aplica el cuestionario
    private String content;   //La descripción del cuestionario
                              //(Es la que se coloca después de la etiqueta
                              //<questionnaire> en el archivo de texto)
    private Vector questions;   //Lista de objetos Question (Las preguntas
                                //del cuestionario)
    private String textOfFile;   //Contenido del archivo de texto
    private TextReader reader;   //Lector de archivos txt (Es el la clase del
                                 //Doctor Ayala "UdlaTextFileResource")
    private Displayable originalDisplayable;   //Desplegable que estaba en pantalla
                                               //en el momento en que se aplica
                                               //el cuestionario
    private Display display;
    private Command nextQuestion;
    private Command previousQuestion;
    private Command endQuestionnaire;
    private Command cancel;


    //-----------------------Variables globales-------------------------------//
    /**
     * Son variables de control que, entre otros métodos, son utilizadas en el
     * método "commandAction" al cual no se le pueden cambiar los parámetros,
     * por lo que es necesario declararlas en esta zona.
     */
    private int actualCorrectAnswers;   //Lleva el control del numero de respuestas
                                        //correctas. Es necesaria para que en caso
                                        //de que el cuestionario sea cancelado,
                                        //no se modifique el número de respuestas
                                        //correctas anterior a la aplicación de
                                        //este.
    private int currentQuestion;   //Indicador de la pregunta que se encuentra
                                   //actualmente activa


    //-------------------------------Constructor------------------------------\\
    public Questionnaire(String aName, String aFileLocation, MIDlet aMidlet){
        //Se llama al constructor de la clase padre
        super(aName);

        //Guardamos los parámetros enviados
        theMidlet = aMidlet;
        fileLocation = aFileLocation;
        name = aName;

        //Inicializamos la lista suponiendo que existe al menos una pregunta e
        //indicando que en caso de que la estructura este llena y se quiera agregar
        //una pregunta mas, aumente su longitud en 1:
        //Vector(Tamaño inicial, Aumento de tamaño en caso de ser necesario)
        questions = new Vector(1,1);

        //Leemos el archivo de texto
        reader = new TextReader(fileLocation);//Se prepara para leer el archivo
        textOfFile = reader.getContent();//Lee el archivo y regresa solo el texto
                                         //como una cadena de caracteres (String)

        //Leemos el texto obtenido anteriormente y creamos los objetos necesarios
        //a partir de este.
        readTextOfFile();

        //Construir comandos
        nextQuestion = new Command("Siguiente", Command.OK, 1);
        previousQuestion = new Command("Atrás", Command.BACK, 1);
        endQuestionnaire = new Command("Fin", Command.OK, 3);
        cancel = new Command("Cancelar", Command.CANCEL, 1);

        //Agregamos los comandos en los desplegables correspondientes
        setCommands();

        //Agregamos el texto de bienvenida del cuestionario
        if(content.length() > 0){
            //Si existe información del cuestionario la añadimos
            this.append("Estas a punto de contestar un cuestionario sobre:\n\n " + content);
        }
        else{
            //Si no existe, lo indicamos
            this.append("No hay información disponible sobre el cuestionario");
        }

        //inicializamos el numero de respuestas correctas en 0 ya que apenas se
        //está construyendo el objeto y lógicamente sabemos que no se ha contestado
        //pero pueden acceder a resultados antes de hacerlo
        numberOfCorrectAnswers = 0;
    }//Fin


//---------------------------------------------------------------------------------\\
//-------------------------------Métodos Públicos----------------------------------\\
//---------------------------------------------------------------------------------\\

    //-----------------------------Método "apply"-----------------------------\\
    //Aplica el cuestionario
    public void apply(){
        //Obtener el display del midlet que fue enviado como parámetro en la
        //construcción del objeto (utilizando la clase correctamente, el
        //midlet en que fue creado)
        display = Display.getDisplay(theMidlet);

        //Obtener el desplegable activo del midlet para poder regresarlo al
        //finalizar el cuestionario
        originalDisplayable = display.getCurrent();

        //Se indica que actualmente no existe alguna pregunta activa
        currentQuestion = 0;

        //El número de respuestas correctas en este momento se coloca en 0
        actualCorrectAnswers = 0;

        //Se coloca este desplegable en pantalla (solo contiene la bienvenida del
        //cuestionario)
        display.setCurrent(this);
    }//Fin


    //-------------------------Método "getName"-------------------------------\\
    public String getName(){
        return name;//Regresa el identificador del cuestionario
    }//Fin


    //--------------------Método "getNumberOfQuestions"-----------------------\\
    public int getNumberOfQuestions(){
        return numberOfQuestions;//Regresa el número de preguntas del cuestionario
    }//Fin


    //-------------------Método "getNumberOfCorrectAnswers"-------------------\\
    public int getNumberOfCorrectAnswers(){
        return numberOfCorrectAnswers;//Regresa el numero de respuestas correctas de
                                      //la última vez que el cuestionario fue contestado
                                      //en su totalidad. 0 si no ha sido contestado
    }//Fin


    //-------------------------Método "toString()"----------------------------\\
    /**
     * Overwrite del método toString de la clase Object
     */
    public String toString(){
        return content;//Regresa el nombre (información) del cuestionario
    }//Fin


//---------------------------------------------------------------------------------\\
//-------------------------------Métodos Privados----------------------------------\\
//---------------------------------------------------------------------------------\\

    //------------------------Método "setCommands"-----------------------------\\
    private void setCommands(){
        //Variables del método
        //Question es un objeto que extiende de Form, por lo tanto es un desplegable
        Question aQuestion;//Pregunta a la que se le agregaran los comandos

        //Agregamos los comandos a las preguntas del cuestionario
        for(int i = 0; i < numberOfQuestions; i = i + 1){//Para todas las preguntas
            //Obtenemos la pregunta correspondiente a la iteración actual
            aQuestion = getQuestion(i);
            //Agregamos el comando para ir a la pregunta anterior (o a la forma
            //de bienvenida si es la primera pregunta)
            aQuestion.addCommand(previousQuestion);
            //Si es la última pregunta agregamos el comando para finalizar el cuestionario
            if(i == numberOfQuestions - 1){
                aQuestion.addCommand(endQuestionnaire);
            }
            //Si no es la ultima agregamos el comando para ir a la pregunta siguiente
            else{
                aQuestion.addCommand(nextQuestion);
            }
            //Se indica que el control de sus comandos lo hará esta clase
            aQuestion.setCommandListener(this);
        }//Fin del for

        //Agregamos los comandos de la forma de bienvenida
        this.addCommand(nextQuestion);
        this.addCommand(cancel);
        this.setCommandListener(this);
    }//Fin


    //------------------------Método readTextOfFile---------------------------\\
    private void readTextOfFile(){
        //Variables del método
        int textPosition;//Indica la posición de un determinado caracter

        //Al iniciar el lector no tenemos ninguna pregunta agregada
        numberOfQuestions = 0;

        //Buscamos el final la primera etiqueta (la cual según el formato es
        //<questionnaire>) y la borramos
        textPosition = textOfFile.indexOf('>') + 1;//String.indexOf(Caracter buscado)
                                                   //Regresa la posición del primer
                                                   //caracter que coincide
        textOfFile = textOfFile.substring(textPosition);//String.substring(inicio de la nueva cadena)

        //Buscamos el inicio de la siguiente etiqueta
        textPosition = textOfFile.indexOf('<');

        //El texto antes de esta etiqueta es el nombre (información) del cuestionario
        content = textOfFile.substring(0,textPosition).trim();//String(inicio, final)
                                                              //String.trim() borra
                                                              //los espacios en blanco
                                                              //al inicio y final de
                                                              //la cadena original

        //Borramos todo lo anterior a la ultima etiqueta encontrada, según el
        //formato esta será <question> o </questionnaire>
        textOfFile = textOfFile.substring(textPosition);

        //Ahora buscamos todas las preguntas en lo que queda del texto (ver que
        //al momento no se han eliminado ninguna etiqueta <question>
        findQuestions();//Busca todas las etiquetas <question> y crea los objetos
                        //Question correspondientes
    }//Fin


    //------------------------Método "findQuestions"--------------------------\\
    private void findQuestions(){
        //Como se elimino todo lo anterior a la ultima etiqueta <question> o
        //</questionnaire> encontrada, el caracter en la posición 1 (iniciando
        //en la posición 0) será 'q' o '/' respectivamente, si es '/' termino de
        //crear todas las preguntas del archivo, de lo contrario se encontró una
        //pregunta más y tendrá que crearla
        while(textOfFile.charAt(1) != '/'){
            createQuestion();//Crea un objeto Question y elimina todo lo referente
                             //a la pregunta encontrada hasta la etiqueta siguiente
                             //a </question> la cual según el formato tiene que
                             //ser otra <question> o un </questionnaire>
        }
    }//Fin


    //-------------------------Método "createQuestion"------------------------\\
    private void createQuestion(){
        //Variables del método
        Question addingQuestion;//Pregunta que se va a crear
        int textPosition;//Indica la posición de un determinado caracter

        //Indicamos que ya encontramos una pregunta mas
        numberOfQuestions = numberOfQuestions + 1;

        //Buscamos el final la primera etiqueta en lo que queda del texto (la
        //cual sabemos que es <question>) y la borramos
        textPosition = textOfFile.indexOf('>') + 1;
        textOfFile = textOfFile.substring(textPosition);

        //Buscamos el inicio de la siguiente etiqueta
        textPosition = textOfFile.indexOf('<');

        //El texto antes de esta etiqueta es el texto de la pregunta
        //Question(identificador, Texto de la pregunta)
        addingQuestion = new Question("Pregunta " + numberOfQuestions ,textOfFile.substring(0, textPosition).trim());

        //Borramos todo lo anterior a la ultima etiqueta encontrada, según el
        //formato esta será <answer> o </question>
        textOfFile = textOfFile.substring(textPosition);

        //Buscamos las respuestas que están antes de la siguiente etiqueta
        //</question> que son las posibles respuestas a la pregunta recién creada
        findAnswers(addingQuestion);//findAnswers(una pregunta); encuentra todas
                                    //las respuestas y las agrega en la pregunta
                                    //que se le envía como parámetro, también borra
                                    //de la cadena todo lo referente a las preguntas
                                    //encontradas

        //Agregamos la pregunta ya totalmente formada en nuestro vector de preguntas
        addQuestion(addingQuestion);

        //Buscamos el final la primera etiqueta en lo que queda del texto (la
        //cual sabemos que es </question>) y la borramos
        textPosition = textOfFile.indexOf('>') + 1;
        textOfFile = textOfFile.substring(textPosition);

        //Buscamos el inicio de la primera etiqueta en lo que queda del texto (la
        //cual según el formato es <question> o </questionnaire>) y borramos todo
        //lo anterior a ella para que sea lo primero que se encuentre en el texto
        textPosition = textOfFile.indexOf('<');
        textOfFile = textOfFile.substring(textPosition);
    }//Fin


    //-----------------------Método "findAnswers"-----------------------------\\
    private void findAnswers(Question aQuestion){
        //Como se elimino todo lo anterior a la ultima etiqueta <answer> o
        //</question> encontrada, el caracter en la posición 1 (iniciando
        //en la posición 0) será 'a' o '/' respectivamente, si es '/' termino de
        //crear todas las respuestas de la pregunta, de lo contrario se encontró una
        //respuesta más y tendrá que crearla
        while(textOfFile.charAt(1) != '/'){
            createAnswer(aQuestion);//Crea un objeto Answer y elimina todo lo referente
                                    //a la respuesta encontrada hasta la etiqueta siguiente
                                    //a </answer> la cual según el formato tiene que
                                    //ser otra <answer> o un </question>, también agrega
                                    //la respuesta encontrada en la pregunta correspondiente
        }
    }//Fin


    //-------------------------Método "createAnswer"--------------------------\\
    private void createAnswer(Question aQuestion){
        //Variables del método
        int textPosition;//Indica la posición de un determinado caracter
        String answer;//En texto de la respuesta encontrada
        String isCorrectText;//El texto entre <isCorrect> y </isCorrect> de la
                             //respuesta encontrada
        boolean isCorrect;//Indica si es correcta o no la respuesta encontrada
        Answer actualAnswer;//Respuesta que se va a crear y agregar

        //Buscamos el final la primera etiqueta en lo que queda del texto (la
        //cual sabemos que es <answer>) y la borramos
        textPosition = textOfFile.indexOf('>') + 1;
        textOfFile = textOfFile.substring(textPosition);

        //Buscamos el inicio de la siguiente etiqueta
        textPosition = textOfFile.indexOf('<');

        //El texto antes de esta etiqueta es el texto de la respuesta
        answer = textOfFile.substring(0, textPosition).trim();

        //Buscamos el final la primera etiqueta en lo que queda del texto (la
        //cual sabemos que es <isCorrect>) y la borramos
        textPosition = textOfFile.indexOf('>') + 1;
        textOfFile = textOfFile.substring(textPosition);

        //Buscamos el inicio de la siguiente etiqueta
        textPosition = textOfFile.indexOf('<');

        //El texto antes de esta etiqueta indica si es o no correcta
        isCorrectText = textOfFile.substring(0, textPosition).trim();

        //Si el texto es "true" isCorrect será 'true', si no lo es, según el
        //formato solo puede ser "false" con lo que el resultado será 'false'
        isCorrect = isCorrectText.equalsIgnoreCase("true");//String.equalseIgnoreCase(texto)
                                                           //true si el texto es igual a la
                                                           //cadena original, no afectan las
                                                           //diferencias entre mayúsculas y
                                                           //minúsculas

        //Creamos el objeto Answer con los resultados anteriores
        actualAnswer = new Answer(answer, isCorrect);//Answer(texto, es o no correcta)

        //Agregamos la respuesta a la pregunta indicada
        aQuestion.addAnswer(actualAnswer);

        //Buscamos el final la primera etiqueta en lo que queda del texto (la
        //cual sabemos que es </isCorrect>) y la borramos
        textPosition = textOfFile.indexOf('>') + 1;
        textOfFile = textOfFile.substring(textPosition);

        //Buscamos el final la primera etiqueta en lo que queda del texto (la
        //cual sabemos que es </answer>) y la borramos
        textPosition = textOfFile.indexOf('>') + 1;
        textOfFile = textOfFile.substring(textPosition);

        //Buscamos el inicio de la primera etiqueta en lo que queda del texto (la
        //cual según el formato es <answer> o </question>) y borramos todo
        //lo anterior a ella para que sea lo primero que se encuentre en el texto
        textPosition = textOfFile.indexOf('<');
        textOfFile = textOfFile.substring(textPosition);
    }//Fin


    //-----------------------Método "getQuestion"-----------------------------\\
    private Question getQuestion(int index){
        return (Question)questions.elementAt(index);//Regresa la pregunta del vector
                                                    //de preguntas en la posición
                                                    //indicada
    }//Fin


    //-------------------------Método "addQuestion""--------------------------\\
    private void addQuestion(Question theQuestion){
        questions.addElement(theQuestion);//Agrega la pregunta indicada en la
                                          //ultima posición del vector
    }//Fin


    //--------------------------Método "commandAction"------------------------\\
    public void commandAction(Command c, Displayable d){
        //Variables del método
        boolean correct;//Indica si la respuesta seleccionada es correcta
        int selectedAnswer;//Indica cual es la respuesta seleccionada

        //Si el comando es "nextQuestion" presentamos la siguiente pregunta
        if(c == nextQuestion){
            //Si existe actualmente una pregunta desplegada
            if(currentQuestion > 0){
                //Verificamos si la respuesta seleccionada es la correcta
                selectedAnswer = this.getQuestion(currentQuestion - 1).getSelectedIndex();
                correct = this.getQuestion(currentQuestion - 1).getAnswer(selectedAnswer).isCorrect();
                if(correct){
                    //Si es correcta aumentamos nuestro contador de respuestas correctas
                    actualCorrectAnswers = actualCorrectAnswers + 1;
                }
            }

            //Desplegamos la siguiente pregunta (o la primera si no hay pregunta
            //desplegada actualmente)
            currentQuestion = currentQuestion + 1;
            display.setCurrent(this.getQuestion(currentQuestion - 1));
        }

        //Si es "previousQuestion" colocamos la pregunta anterior o el desplegable
        //de bienvenida si es la primera pregunta
        else if(c == previousQuestion){
            //Indicamos que estamos en la pregunta anterior
            currentQuestion = currentQuestion - 1;

            //Si la anterior no es una pregunta, mostramos la bienvenida
            if(currentQuestion == 0){
                display.setCurrent(this);
            }
            //Si es una pregunta
            else{
                //Verificamos si la respuesta era correcta
                selectedAnswer = this.getQuestion(currentQuestion - 1).getSelectedIndex();
                correct = this.getQuestion(currentQuestion - 1).getAnswer(selectedAnswer).isCorrect();
                if(correct){
                    //Si lo era restamos una respuesta correcta que volverá a ser
                    //evaluada al terminar la pregunta
                    actualCorrectAnswers = actualCorrectAnswers - 1;
                }

                //Desplegamos la pregunta (o la bienvenida si es la pregunta "0")
                display.setCurrent(this.getQuestion(currentQuestion - 1));
            }
        }

        //Si es "cancel" terminamos el cuestionario sin salvar el resultado
        else if(c == cancel){
            //Mostramos el desplegable que estaba antes de aplicar el cuestionario
            display.setCurrent(originalDisplayable);
        }

        //Si no es ningún otro, el comando es "endQuestionnaire" y termina el
        //el cuestionario salvando el resultado
        else{
            //Verificamos si la respuesta seleccionada es la correcta
            selectedAnswer = this.getQuestion(currentQuestion - 1).getSelectedIndex();
            correct = this.getQuestion(currentQuestion - 1).getAnswer(selectedAnswer).isCorrect();
            if(correct){
                ////Si es correcta aumentamos nuestro contador de respuestas correctas
                actualCorrectAnswers = actualCorrectAnswers + 1;
            }

            //Salvamos el número de respuestas correctas
            numberOfCorrectAnswers = actualCorrectAnswers;

            //Mostramos el desplegable que estaba antes de aplicar el cuestionario
            display.setCurrent(originalDisplayable);
        }
    }//Fin

}//Fin de la clase Questionnaire
Comments