vista.ui.VistaGenerarEstadisticas.java Source code

Java tutorial

Introduction

Here is the source code for vista.ui.VistaGenerarEstadisticas.java

Source

/*
 * Copyright (C) 2015 Jess Donaldo Osornio Hernndez
 *
 * This file is part of MatExmenes.
 *
 * MatExmenes is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * MatExmenes is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package vista.ui;

import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.embed.swing.JFXPanel;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.image.WritableImage;
import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;
import modelo.dto.CursoDTO;
import modelo.dto.ExamenDTO;
import modelo.dto.GrupoDTO.Turno;
import modelo.dto.TablaEstadisticas;
import modelo.dto.UsuarioDTO;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import vista.controlador.CVGenerarEstadisticas;
import vista.interfaz.InterfaceVista;

/**
 * JPanel que mostrar la interfaz grfica de Generar Estadsticas
 *
 * @author Jesus Donaldo Osornio Hernndez
 * @version 1 18 Mayo 2015
 */
public class VistaGenerarEstadisticas extends javax.swing.JPanel implements InterfaceVista, AncestorListener {

    /**
     * Controlador de la vista del caso de uso Generar Estadsticas, funciona
     * para manejar la informacin obtenida en la vista para comunicarse con las
     * capas inferiores
     */
    private CVGenerarEstadisticas controlVista;
    /**
     * Interface de comunicacin con la interfaz padre, la cul sirve para
     * comunicarse con ella y recibir mensajes para mostrar otras vistas. En ese
     * caso es utilizada para comunicarse con el JFrame Principal
     */
    private InterfaceVista padre;

    /**
     * JFrame que ser utilizado para mostrar la grfica de estadsticas
     * resultante
     */
    private JFrame frmGrafica;
    /**
     * JFXPanel que ser utilizado para contener la grfica de barras generada
     * por JavaFX
     */
    private JFXPanel fxpnlGrafica;
    /**
     * Grfica de barras donde se ilustrarn las estadsticas seleccionadas por
     * el usuario
     */
    private BarChart bcGrafica;

    /**
     * Objeto que agrupa lgicamente los radio buttons para seleccionar el tipo
     * de de estadstica que se desea generar
     */
    private final ButtonGroup tipoEstadistica;

    /**
     * Lista de ndices de seleccin de las filas que se acomodan de acuerdo al
     * orden de seleccin de las filas de la tabla. Representan los exmenes que
     * se desean ilustrar al generar las estadsticas
     */
    private List<Integer> indexesExamen = new ArrayList<>();

    /**
     * Bandera que sirve para que el evento de cambio no se dispare en los
     * combobox al ingresar nuevos datos, para evitar que el sistema tenga
     * resultados inesperados
     */
    private boolean noSelect;

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnCancelar;
    private javax.swing.JButton btnGenerar;
    private javax.swing.JComboBox cmbCurso;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblCurso;
    private javax.swing.JLabel lblExamenes;
    private javax.swing.JLabel lblTitulo1;
    private javax.swing.JPanel pnlEstadisticas;
    private javax.swing.JRadioButton rbtnGrados;
    private javax.swing.JRadioButton rbtnGrupos;
    private javax.swing.JRadioButton rbtnTurnos;
    private javax.swing.JTable tblExamenes;
    // End of variables declaration//GEN-END:variables

    /**
     * Crea un objeto VistaGenerarEstadisticas e inicializa sus atributos,
     * inicializa el thread JavaFX y los componentes necesarios para mostrar la
     * grfica y agrega los listeners necesarios
     */
    public VistaGenerarEstadisticas() {
        initComponents();
        initFX();

        tipoEstadistica = new ButtonGroup();

        tipoEstadistica.add(rbtnGrupos);
        tipoEstadistica.add(rbtnGrados);
        tipoEstadistica.add(rbtnTurnos);

        initListeners();

        addAncestorListener(this);
    }

    /**
     * Este mtodo sirve para inicializar el thread JavaFX para mostrar la
     * grfica y debe ser llamado al principio, en el constructor.
     */
    private void initFX() {
        //Crea los paneles JavaFX necesarios
        fxpnlGrafica = new JFXPanel();
        JFXPanel fxpnlBoton = new JFXPanel();
        JFXPanel fxpnlBotonExcel = new JFXPanel();

        fxpnlGrafica.setBounds(0, 0, 800, 500);
        fxpnlBoton.setBounds(420, 520, 150, 30);
        fxpnlBotonExcel.setBounds(600, 520, 180, 30);

        //Asigna un listener al boton JavaFX para guardar la grfica como imagen
        //en el equipo
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                Button btnGuardar = new Button("Guardar Grfica");
                Button btnExportar = new Button("Exportar a Excel");

                //Agregar los listeners
                btnGuardar.setOnAction(new EventHandler<ActionEvent>() {

                    @Override
                    public void handle(ActionEvent event) {
                        guardarGrafica();
                    }

                });

                btnExportar.setOnAction(new EventHandler<ActionEvent>() {

                    @Override
                    public void handle(ActionEvent event) {
                        exportarAExcel();
                    }

                });

                //Crear la scene y lo necesario para mostrar la grafica
                Scene scene = new Scene(btnGuardar);
                fxpnlBoton.setScene(scene);

                scene = new Scene(btnExportar);
                fxpnlBotonExcel.setScene(scene);
            }
        });

        frmGrafica = new JFrame("Estadsticas");
        frmGrafica.setLayout(null);
        frmGrafica.add(fxpnlGrafica);
        frmGrafica.add(fxpnlBoton);
        frmGrafica.add(fxpnlBotonExcel);
        frmGrafica.setSize(800, 600);
        frmGrafica.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frmGrafica.setResizable(false);
        frmGrafica.setLocationRelativeTo(null);
        frmGrafica.setIconImage(new ImageIcon(getClass().getResource("/recursos/icono16.png")).getImage());

    }

    /**
     * Este mtodo inicializa y agrega los listeners necesarios para que la
     * vista funcione.
     */
    private void initListeners() {
        //Para guardar el primer seleccionado como primer examen
        tblExamenes.getModel().addTableModelListener(new TableModelListener() {

            //Listener para cuando haya cambios en la tabla. Para ir guardando
            //Las selecciones de los exmenes en tiempo real.
            @Override
            public void tableChanged(TableModelEvent e) {
                //Evitar que se actualice inesperadamente
                if (!noSelect) {
                    int index = tblExamenes.getSelectedRow();

                    if ((boolean) tblExamenes.getValueAt(index, 0)) {
                        //Si lo seleccion agregarlo a la lista

                        //Si sobrepas el lmite no permitir que seleccione ms
                        if (indexesExamen.size() == 2) {
                            tblExamenes.setValueAt(false, index, 0);
                        } else {
                            indexesExamen.add(index);
                        }
                    } else {
                        //Si lo deseleccion eliminarlo de la lista
                        for (int i = 0; i < indexesExamen.size(); i++) {
                            if (indexesExamen.get(i) == index) {
                                indexesExamen.remove(i);
                            }
                        }
                    }
                }
            }
        });

        //Listener para el cmbCurso
        cmbCurso.addActionListener(new ActionListener() {

            //Consultar los exmenes en cuanto se seleccione un curso en el
            //cmbCurso
            @Override
            public void actionPerformed(java.awt.event.ActionEvent e) {
                if (!noSelect) {
                    noSelect = true;
                    consultarExamenes();
                }
            }

        });

        //Listener para la ventana, cuando se vaya a cerrar
        frmGrafica.addWindowListener(new WindowListener() {

            @Override
            public void windowOpened(WindowEvent e) {
            }

            @Override
            public void windowClosing(WindowEvent e) {
                //Habilitar al padre, cerrar la ventana y terminar con el thread
                Platform.exit();
                ((JFrame) padre).setEnabled(true);
                frmGrafica.setVisible(false);
            }

            @Override
            public void windowClosed(WindowEvent e) {
                //Habilitar al padre, cerrar la ventana y terminar con el thread
                Platform.exit();
                ((JFrame) padre).setEnabled(true);
                frmGrafica.setVisible(false);
            }

            @Override
            public void windowIconified(WindowEvent e) {
            }

            @Override
            public void windowDeiconified(WindowEvent e) {
            }

            @Override
            public void windowActivated(WindowEvent e) {
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
            }
        });
    }

    /**
     * Almacena el control de la vista
     *
     * @param controlVista El objeto encargado de realizar comunicar la vista
     * con las capas inferiores para acceder a los datos
     */
    public void setControlador(CVGenerarEstadisticas controlVista) {
        this.controlVista = controlVista;
    }

    /**
     * Almacena la interface del JFrame principal.
     *
     * @param padre Interface para interactuar con el JFrame principal.
     */
    public void setPadre(InterfaceVista padre) {
        this.padre = padre;
    }

    /**
     * Este mtodo es utilizado para consultar y mostrar los cursos disponibles
     * en la base de datos, mediante la utilizacin del controlVista. En caso de
     * que no exista ningn curso se mostrar un mensaje y se regresar a la
     * vista principal.
     */
    private void consultarCursos() {
        //la lista de cursos obtenida desde la base de datos por el controlVista
        List<CursoDTO> cursos = controlVista.obtenerCursos();

        //Si hay cursos...
        if (cursos != null && !cursos.isEmpty()) {
            mostrarCursos(cursos);
        } else {
            //Si no hay mostrar un mensaje, regresar a la vista principal y
            //limpiar la vista actual
            JOptionPane.showMessageDialog(this, "No hay cursos");
            padre.mostrarVista(Vista.HOME);
            limpiar();
        }
    }

    /**
     * Este mtodo es utilizado para mostrar una lista de cursos en el
     * componente comboBox de la vista para mostrar los cursos disponibles.
     *
     * @param cursos una lista de cursos CursoDTO a ser mostrada en el comboBox
     * de la vista
     */
    private void mostrarCursos(List<CursoDTO> cursos) {
        //Para limpiar el cmbCurso de informacin previa
        cmbCurso.removeAllItems();

        //Recorrer todos los elementos de la lista para mostrarlos en el comboBox
        for (CursoDTO curso : cursos) {
            cmbCurso.addItem(curso.getNombre());
        }

        //Deselecciona el comboBox y permite la funcionalidad correcta del
        //listener del cmbCurso al igualar la bandera a falso
        cmbCurso.setSelectedIndex(-1);
        noSelect = false;
    }

    /**
     * Este mtodo es utilizado para consultar y mostrar los exmenes en base al
     * curso seleccionado, mediante la utilizacin del controlVista. En caso de
     * que no exista ningn examen se mostrar un mensaje y se permitir volver
     * a realizar otra seleccin.
     */
    private void consultarExamenes() {
        //La lista de exmenes obtenidos por el controlVista
        List<ExamenDTO> examenes = controlVista.obtenerExamenesPorCurso(cmbCurso.getSelectedItem().toString());

        //Si hay exmenes resultantes mostrarlos en la vista
        if (examenes != null && !examenes.isEmpty()) {
            mostrarExamenes(examenes);
        } else {
            JOptionPane.showMessageDialog(this, "No hay examenes");
            ((DefaultTableModel) tblExamenes.getModel()).setRowCount(0);
        }

        noSelect = false;
        indexesExamen = new ArrayList<>();
    }

    /**
     * Este mtodo es utilizado para mostrar una lista de exmenes en el
     * componente table de la vista para mostrar los exmenes ingresados.
     *
     * @param examenes una lista de examenes ExamenDTO a ser mostrada en la
     * table de la vista
     */
    private void mostrarExamenes(List<ExamenDTO> examenes) {
        DefaultTableModel model = (DefaultTableModel) tblExamenes.getModel();

        model.setRowCount(0);
        //Mostrar cada reactivo, no remover, si no buscar por medio del for
        for (ExamenDTO examen : examenes) {
            Object[] datos = new Object[6];

            datos[0] = false;
            datos[1] = examen.getId();
            datos[2] = examen.getNombre();
            datos[3] = examen.getFechaCreacion();
            datos[4] = examen.getFechaModificacion();
            if (examen.getAutor() != null) {
                datos[5] = examen.getAutor().getUsuario();
            } else {
                datos[5] = "Sin autor";
            }

            model.addRow(datos);
        }
    }

    /**
     * Este mtodo es utilizado para mostrar el objeto BarChart grficamente
     * como una grfica de barras en el frame emergente, inhabilitando esta
     * vista por el momento que el frame est activo.
     *
     * @param grafica el objeto BarChart que se mostrar como grfica de barras
     */
    private void mostrarGrafica(BarChart grafica) {
        //deshabilita el padre de esta vista y muestra el frame que contendr
        //la grfica
        frmGrafica.setVisible(true);
        ((JFrame) padre).setEnabled(false);

        //Thread de JavaFX para correr la grafica
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                //Crear la scene y lo necesario para mostrar la grafica
                Scene scene = new Scene(grafica);
                fxpnlGrafica.setScene(scene);
            }
        });

    }

    /**
     * Este mtodo es utilizado para generar una grfica de barras en base a los
     * parmetros de entrada para generar el tipo de grfica correspondiente. El
     * resultado es mostrar la grfica en una ventana emergente si todo sali
     * bien o mostrar un mensaje indicando la razn de porque no se gener la
     * grfica
     *
     * @param tipo el tipo de grfica que se va a generar, los valores aceptados
     * son (Grupo, Grado, Turno) para cada tipo de estadstica respectivamente
     *
     * @param ejeX la etiqueta que llevar el ejeX
     * @param ejeY la etiqueta que llevar el ejeY
     * @param titulo la etiqueta que llevar el ttulo de la grfica
     */
    private void generarGrafica(String tipo, String ejeX, String ejeY, String titulo) {

        //Comprobar que se seleccionaron uno o dos examenes
        if (indexesExamen.size() > 0) {
            TablaEstadisticas tabla;
            //Elegir que tipo de estadstica realizar
            if (tipo.equals("Grupo")) {
                tabla = controlVista.generarEstadisticasPorGrupos(indexesExamen);
            } else if (tipo.equals("Grado")) {
                tabla = controlVista.generarEstadisticasPorGrados(indexesExamen);
            } else {
                //Turnos
                tabla = controlVista.generarEstadisticasPorTurnos(indexesExamen);
            }

            //Si la tabla que se regresa del controlVista es null significa que
            //no existen grupos
            if (tabla == null) {
                JOptionPane.showMessageDialog(this, "No hay grupos");
            } else {
                //Para saber si hay aunque sea un promedio en la tabla
                boolean ok = false;
                for (int r = 0; r < tabla.getRowCount(); r++) {
                    for (int c = 0; c < tabla.getColumnCount(); c++) {

                        //Igualar todos los datos null a 0.0
                        if (tabla.getValueAt(r, c) == null) {
                            tabla.setValueAt(0.0, r, c);
                        } else {
                            ok = true;
                        }
                    }
                }

                if (!ok) {
                    //Si la tabla est vaca
                    JOptionPane.showMessageDialog(this, "No hay exmenes " + "contestados");
                } else {
                    //Crear grfica de barras
                    bcGrafica = crearGrafica(tabla, ejeX, ejeY, titulo);

                    //Mostrar la grfica de barras
                    mostrarGrafica(bcGrafica);
                }
            }
        } else {
            JOptionPane.showMessageDialog(this, "Seleccione uno o dos exmenes");
        }
    }

    /**
     * Este mtodo es utilizado para crear un objeto BarChart (grfica de
     * barras) manipulable en la interfaz en base a un objeto tablaEstadsticas
     * que contiene los datos de calificacin y exmenes a graficar.
     *
     * @param tabla el objeto TablaEstadisticas que contiene las calificaciones
     * y los grupos/grados/turnos junto con los dos exmenes a graficar
     *
     * @param ejeX la etiqueta del eje X
     * @param ejeY la etiqueta del eje Y
     * @param titulo la etiqueta del ttulo de la grfica
     * @return un objeto BarChart con toda la informacin de la tabla vaciada.
     */
    private BarChart crearGrafica(TablaEstadisticas tabla, String ejeX, String ejeY, String titulo) {

        //Crea el eje X en base a las columnas de la tabla y le asigna la etiqueta
        //correspondiente
        CategoryAxis ejeHorizontal = new CategoryAxis();
        ejeHorizontal.setCategories(FXCollections.<String>observableArrayList(tabla.getColumnas()));
        ejeHorizontal.setLabel(ejeX);

        double tickUnit = tabla.getTickUnit();

        //Crea un eje vertical numrico y le asigna la etiqueta correspondiente
        NumberAxis ejeVertical = new NumberAxis();
        ejeVertical.setTickUnit(tickUnit);
        ejeVertical.setLabel(ejeY);

        //Crea un nuevo objeto BarChart en base a la matriz de datos de la tabla
        final BarChart grafica = new BarChart(ejeHorizontal, ejeVertical, tabla.getBarChartDatos());

        //Pasa la informacin de cada celda de la tabla al objeto BarChart
        Platform.runLater(new Runnable() {
            public void run() {
                for (int row = 0; row < tabla.getRowCount(); row++) {
                    for (int column = 0; column < tabla.getColumnCount(); column++) {
                        //Crea una nueva serie de la grfica, osea una fila de la
                        //tabla. La cual contiene las calificaciones de un examen
                        //en todos los grupos/grados/turnos segn sea el caso
                        XYChart.Series<String, Number> s = (XYChart.Series<String, Number>) grafica.getData()
                                .get(row);
                        //pone el nombre a cada serie con el nombre del examen...
                        s.setName(tblExamenes.getValueAt(indexesExamen.get(row), 2).toString());
                        //Obtiene la calificacin de cada grupo/grado/turno
                        //en base a la columna correspondiente de la tabla
                        BarChart.Data data = s.getData().get(column);
                        Object value = tabla.getValueAt(row, column);
                        data.setYValue(value);
                    }

                }
                //Nombra el ttulo de la grfica con la etiqueta ttulo de entrada
                grafica.setTitle(titulo);

            }
        });

        return grafica;
    }

    /**
     * Este mtodo sirve para mostrar un dalogo grfico para que el usuario
     * seleccione un archivo de destino para guardar un archivo
     *
     * @param extension una cadena con el nombre del tipo de archivo que se
     * puede seleccionar
     * @param titulo una cadena con el nombre del dilogo
     * @param botonOK una cadena con el nombre del botn de aprovacin
     * @param tooltipOk una cadena con el nombre del tooltip del botn de
     * aprovacin
     *
     * @return el objeto File con la direccin del archivo en caso de que haya
     * seleccionado uno vlido, regresa null en caso contrario.
     */
    private File elegirArchivo(String extension, String titulo, String botonOk, String tooltipOk) {
        JFileChooser chooser = new JFileChooser();
        FileFilter filter = new FileNameExtensionFilter(extension.toUpperCase() + " file",
                new String[] { extension });

        //Inicializar atributos del dilogo de archivos
        chooser.addChoosableFileFilter(filter);
        chooser.setFileFilter(filter);
        chooser.setDialogTitle(titulo);
        chooser.setApproveButtonText(botonOk);
        chooser.setApproveButtonToolTipText(tooltipOk);
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        chooser.setMultiSelectionEnabled(false);

        //Mostrar el dilogo de archivos
        chooser.showOpenDialog(null);

        //Obtener el archivo en el que se quiere guardar la imagen
        return chooser.getSelectedFile();
    }

    /**
     * Este mtodo sirve para guardar la grfica como una imagen png en la
     * ubicacin especificada por el usuario. Este mtodo es llamado al
     * seleccionar Guardar en el JFrame emergente.
     */
    private void guardarGrafica() {
        //Crear una imagen de la grfica
        WritableImage imagen = bcGrafica.snapshot(new SnapshotParameters(), null);

        //Obtener el archivo en el que se quiere guardar la imagen
        File file = elegirArchivo("png", "Guardar Grfica", "Guardar",
                "Guarda " + "la grfica en la ruta seleccionada");

        try {
            //Si el archivo no termina en .png concatenrselo
            if (file != null) {
                String path = file.getAbsolutePath();
                if (!path.endsWith(".png")) {
                    path += ".png";
                    file = new File(path);
                }

                //Escribir la imagen en la ruta especificada
                ImageIO.write(SwingFXUtils.fromFXImage(imagen, null), "png", file);
            }
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    /**
     * Este mtodo sirve para exportar a un libro de trabajo en Excel los datos
     * de la grfica actual.
     *
     */
    private void exportarAExcel() {
        //Abrir el nuevo libro de trabajo, con el nombre de archivo elegido por
        //el usuario
        //Obtener el archivo en el que se quiere guardar
        File file = elegirArchivo("xlsx", "Exportar datos a Excel", "Exportar",
                "Guarda el archivo de Excel en la ruta seleccionada");

        //Verificar que se haya elegido un nombre correcto
        try {
            //Crear el workbook
            Workbook workbook = new XSSFWorkbook();

            //Si el archivo no termina en .xls concatenrselo
            if (file != null) {
                String path = file.getAbsolutePath();
                if (!path.endsWith(".xlsx")) {
                    path += ".xlsx";
                    file = new File(path);
                }

                //Escribir las hojas en el workbook
                for (int index : indexesExamen) {
                    TablaEstadisticas calificaciones = controlVista.obtenerCalificacionesPorExamen(index);

                    if (calificaciones != null) {
                        //Obtener el nombre del examen a guardar...
                        String nombreExamen = (String) tblExamenes.getValueAt(index, 2);

                        //Crear la hoja
                        crearHoja(workbook, nombreExamen, calificaciones);
                    }

                }

                //Escribirlo en el sistema de archivos
                try (FileOutputStream out = new FileOutputStream(file)) {
                    workbook.write(out);
                }
            }
        } catch (IOException e) {
            System.out.println(e);
        }

    }

    /**
     * Este mtodo sirve para crear una nueva hoja de Excel en el libro de
     * trabajo seleccionado, no es trabajo de este mtodo guardar los cambios en
     * el sistema de archivos, slo agrega la hoja de Excel al libro de trabajo
     * en memoria.
     *
     * @param workbook el objeto Workbook al que se le adjuntar la nueva hoja
     * de Excel
     * @param nombre un String con el nombre que tendr la nueva hoja de Excel
     * @param datos un objeto TablaEstadisticas con los datos y los nombres de
     * columnas que sern agregados a la hoja
     */
    private void crearHoja(Workbook workbook, String nombre, TablaEstadisticas datos) {
        //Crear la hoja
        CreationHelper createHelper = workbook.getCreationHelper();
        Sheet nuevaHoja = workbook.createSheet(WorkbookUtil.createSafeSheetName(nombre));

        //Escribir los nombres de las columnas en la hoja
        Row headers = nuevaHoja.createRow(0);

        for (int i = 0; i < datos.getColumnCount(); i++) {
            //Crear headers con estilo
            Cell cell = headers.createCell(i);
            CellStyle style = crearEstiloCelda(workbook, IndexedColors.BLACK, CellStyle.BORDER_THICK,
                    CellStyle.ALIGN_CENTER, CellStyle.VERTICAL_CENTER);

            cell.setCellValue(createHelper.createRichTextString(datos.getColumnName(i)));
            cell.setCellStyle(style);

            //Autoajustar
            nuevaHoja.autoSizeColumn(i);
        }

        //Escribir los datos de la tabla en la hoja
        for (int i = 0; i < datos.getRowCount(); i++) {
            Row fila = nuevaHoja.createRow(i + 1);
            CellStyle style = crearEstiloCelda(workbook, IndexedColors.GREEN, CellStyle.BORDER_THIN, (short) -18,
                    (short) -18);

            for (int j = 0; j < datos.getColumnCount(); j++) {
                Cell cell = fila.createCell(j);

                //Escribir de acuerdo al tipo de dato
                if (datos.getColumnClass(j).equals(String.class)) {
                    cell.setCellValue(createHelper.createRichTextString(datos.getValueAt(i, j).toString()));

                } else if (datos.getColumnClass(j).equals(Integer.class)) {
                    cell.setCellValue((int) datos.getValueAt(i, j));

                } else if (datos.getColumnClass(j).equals(Double.class)) {
                    cell.setCellValue((double) datos.getValueAt(i, j));

                } else if (datos.getColumnClass(j).equals(Turno.class)) {
                    cell.setCellValue(((Turno) datos.getValueAt(i, j)).toString());

                }

                //Agregar el estilo
                cell.setCellStyle(style);
            }
        }

    }

    /**
     * Este mtodo sirve para crear un estilo de celda bsico con un estilo de
     * borde y color para borde
     *
     * @param workbook el objeto Workbook dueo de la celda
     * @param borderColor el color del borde
     * @param borderStyle el estilo del borde
     * @param halign la alineacin horizontal de la celda o un nmero negativo
     * si no se desea tener alineacin horizontal
     * @param valign la alineacin vertical de la celda o un nmero negativo si
     * no se desea tener alineacin vertical
     *
     * @return un objeto CellStyle con el estilo de la celda creado
     */
    private CellStyle crearEstiloCelda(Workbook workbook, IndexedColors borderColor, short borderStyle,
            short halign, short valign) {
        CellStyle style = workbook.createCellStyle();

        //Estilo centrado y con bordes
        style.setBorderBottom(borderStyle);
        style.setBottomBorderColor(borderColor.getIndex());
        style.setBorderLeft(borderStyle);
        style.setLeftBorderColor(borderColor.getIndex());
        style.setBorderRight(borderStyle);
        style.setRightBorderColor(borderColor.getIndex());
        style.setBorderTop(borderStyle);
        style.setTopBorderColor(borderColor.getIndex());

        if (halign >= 0) {
            style.setAlignment(halign);
            style.setVerticalAlignment(valign);
        }

        return style;
    }

    /**
     * Inicializa los atributos grficos y los coloca en su posicin.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        tblExamenes = new javax.swing.JTable();
        lblExamenes = new javax.swing.JLabel();
        lblCurso = new javax.swing.JLabel();
        cmbCurso = new javax.swing.JComboBox();
        lblTitulo1 = new javax.swing.JLabel();
        pnlEstadisticas = new javax.swing.JPanel();
        rbtnGrupos = new javax.swing.JRadioButton();
        rbtnTurnos = new javax.swing.JRadioButton();
        rbtnGrados = new javax.swing.JRadioButton();
        btnGenerar = new javax.swing.JButton();
        btnCancelar = new javax.swing.JButton();

        setPreferredSize(new java.awt.Dimension(800, 600));

        tblExamenes.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
        tblExamenes.setModel(new javax.swing.table.DefaultTableModel(new Object[][] {

        }, new String[] { "[X]", "Id", "Nombre", "Fecha Creacin", "Fecha Modificacin", "Autor" }) {
            Class[] types = new Class[] { java.lang.Boolean.class, java.lang.Integer.class, java.lang.String.class,
                    java.lang.Object.class, java.lang.Object.class, java.lang.String.class };
            boolean[] canEdit = new boolean[] { true, false, false, false, false, false };

            public Class getColumnClass(int columnIndex) {
                return types[columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit[columnIndex];
            }
        });
        tblExamenes.setToolTipText("Selecciona los exmenes que desee en el orden que desea que se comparen");
        tblExamenes.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        tblExamenes.getTableHeader().setReorderingAllowed(false);
        jScrollPane1.setViewportView(tblExamenes);
        if (tblExamenes.getColumnModel().getColumnCount() > 0) {
            tblExamenes.getColumnModel().getColumn(0).setPreferredWidth(20);
        }

        lblExamenes.setFont(new java.awt.Font("Arial", 1, 16)); // NOI18N
        lblExamenes.setText("Seleccione uno o dos exmenes:");

        lblCurso.setFont(new java.awt.Font("Arial", 1, 14)); // NOI18N
        lblCurso.setText("Curso:");

        cmbCurso.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
        cmbCurso.setToolTipText("filtrar la bsqueda por curso");
        cmbCurso.setPreferredSize(new java.awt.Dimension(78, 25));

        lblTitulo1.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N
        lblTitulo1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblTitulo1.setText("Generar Estadsticas");

        pnlEstadisticas.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Tipo de Estadstica",
                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
                javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 1, 14))); // NOI18N

        rbtnGrupos.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N
        rbtnGrupos.setText("Por Grupos");
        rbtnGrupos.setToolTipText("El examen puede ser visto y utilizado por todos los maestros");

        rbtnTurnos.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N
        rbtnTurnos.setText("Por Turnos");
        rbtnTurnos.setToolTipText("El examen puede ser visto y utilizado por todos los maestros");

        rbtnGrados.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N
        rbtnGrados.setText("Por Grados");
        rbtnGrados.setToolTipText("El examen puede ser visto y utilizado por todos los maestros");

        javax.swing.GroupLayout pnlEstadisticasLayout = new javax.swing.GroupLayout(pnlEstadisticas);
        pnlEstadisticas.setLayout(pnlEstadisticasLayout);
        pnlEstadisticasLayout.setHorizontalGroup(pnlEstadisticasLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(pnlEstadisticasLayout.createSequentialGroup().addGap(26, 26, 26).addComponent(rbtnGrupos)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 32, Short.MAX_VALUE)
                        .addComponent(rbtnGrados).addGap(26, 26, 26).addComponent(rbtnTurnos).addGap(21, 21, 21)));
        pnlEstadisticasLayout.setVerticalGroup(
                pnlEstadisticasLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(pnlEstadisticasLayout.createSequentialGroup().addGap(17, 17, 17)
                                .addGroup(pnlEstadisticasLayout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                        .addComponent(rbtnGrupos, javax.swing.GroupLayout.PREFERRED_SIZE, 30,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(rbtnTurnos, javax.swing.GroupLayout.PREFERRED_SIZE, 30,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(rbtnGrados, javax.swing.GroupLayout.PREFERRED_SIZE, 30,
                                                javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

        btnGenerar.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
        btnGenerar.setText("Generar");
        btnGenerar.setPreferredSize(new java.awt.Dimension(77, 30));
        btnGenerar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                generarGrafica(evt);
            }
        });

        btnCancelar.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
        btnCancelar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/recursos/cancelar24.png"))); // NOI18N
        btnCancelar.setText("Cancelar");
        btnCancelar.setPreferredSize(new java.awt.Dimension(77, 30));
        btnCancelar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCancelarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(lblTitulo1, javax.swing.GroupLayout.PREFERRED_SIZE, 800,
                        javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(layout.createSequentialGroup().addGap(75, 75, 75).addComponent(lblCurso)
                        .addGap(18, 18, 18).addComponent(cmbCurso, javax.swing.GroupLayout.PREFERRED_SIZE, 309,
                                javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(layout.createSequentialGroup().addGap(214, 214, 214).addComponent(pnlEstadisticas,
                        javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
                        javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(layout.createSequentialGroup().addGap(75, 75, 75)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addGroup(layout.createSequentialGroup()
                                        .addComponent(btnGenerar, javax.swing.GroupLayout.PREFERRED_SIZE, 112,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(18, 18, 18).addComponent(btnCancelar,
                                                javax.swing.GroupLayout.PREFERRED_SIZE, 115,
                                                javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 665,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addContainerGap().addComponent(lblExamenes).addGap(268, 268, 268)));
        layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup().addComponent(lblTitulo1).addGap(34, 34, 34)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(layout.createSequentialGroup().addGap(4, 4, 4).addComponent(lblCurso))
                                .addComponent(cmbCurso, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18).addComponent(lblExamenes).addGap(18, 18, 18)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 247,
                                javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(28, 28, 28)
                        .addComponent(pnlEstadisticas, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(btnGenerar, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(btnCancelar, javax.swing.GroupLayout.PREFERRED_SIZE, 30,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addContainerGap()));
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Este mtodo sirve para generar una grfica de barrras en base a las
     * selecciones de exmenes y tipo de estadstica hechas por el usuario. Este
     * mtodo es llamado al seleccionar la opcin Generar
     *
     * @param evt en objeto ActionEvent generado por el evento
     */
    private void generarGrafica(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generarGrafica
        //Obtener la seleccin del tipo de estadstica
        ButtonModel seleccion = tipoEstadistica.getSelection();

        //Si hay seleccin comparar con cada botn para hacer la grfica correcta
        if (seleccion != null) {
            if (rbtnGrados.getModel() == seleccion) {
                generarGrafica("Grado", "Grados", "Calificacin", "Estadsticas " + "por Grados");

            } else if (rbtnGrupos.getModel() == seleccion) {
                generarGrafica("Grupo", "Grupos", "Calificacin", "Estadsticas " + "por Grupos");
            } else {
                //Por turnos
                generarGrafica("Turno", "Turnos", "Calificacin", "Estadsticas " + "por Turnos");
            }
        } else {
            //Si no hay seleccin mostrar un mensaje
            JOptionPane.showMessageDialog(this, "Seleccione una tipo de " + "Estadstica");
        }
    }//GEN-LAST:event_generarGrafica

    private void btnCancelarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelarActionPerformed
        padre.mostrarVista(Vista.HOME);
        limpiar();
    }//GEN-LAST:event_btnCancelarActionPerformed

    @Override
    public void mostrarVistaConEntidad(Object entidad, Vista vista) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mostrarVista(Vista vista) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mostrarEntidad(Object entidad) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean confirmarCambio() {
        boolean cambiar = false;
        int ok = JOptionPane.showConfirmDialog(this, "Est seguro de que "
                + "quiere cambiar de pantalla?\nTodos los cambios no " + "guardados se perdern", "Confirmacin",
                JOptionPane.YES_NO_OPTION);
        if (ok == JOptionPane.YES_OPTION) {
            cambiar = true;
        }
        return cambiar;
    }

    @Override
    public UsuarioDTO obtenerUsuarioActual() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void limpiar() {
        //Limpiar
        noSelect = true;
        cmbCurso.removeAllItems();
        ((DefaultTableModel) tblExamenes.getModel()).setRowCount(0);
        tipoEstadistica.clearSelection();

        controlVista.liberarMemoria();
    }

    /**
     * Este mtodo es invocado cuando se muestra por primera vez esta vista
     *
     * @param event el objeto AncestorEvent generado por el evento
     */
    @Override
    public void ancestorAdded(AncestorEvent event) {
        if (isShowing()) {
            noSelect = true;
            consultarCursos();
        }
    }

    @Override
    public void ancestorRemoved(AncestorEvent event) {
    }

    @Override
    public void ancestorMoved(AncestorEvent event) {
    }
}