Title: Actividad - Formulario de captura
Course: 2025 - LI - Bases de Datos Emergentes 2-1 y 2-2

/**
 * Formulario.java
 */
package agenda;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * Clase utilitaria para mostrar un diálogo que pide múltiples
 * valores.
 */
public class Formulario extends JOptionPane {

    /**
     * Atributo para alojar los campos que formaran la ventana del formulario
     */
    private JTextField camposFormulario[];

    /**
     * Atributo para la opción por defecto del formulario
     */
    private boolean aceptar;

    /**
     * Atributo para definir la estructura visual del formulario
     */
    private int COLUMNAS = 20;

    /**
     * Método para abrir un cuadro de diálogo solicitando varios elementos de
     * entrada de datos.
     *
     * @param origen el componente de interfaz gráfica a donde se mostrará el
     * formulario
     * @param campos los campos de captura que se mostrarán en el formulario
     * @param valoresIniciales los valores iniciales para cada elemento. Este
     * parámetro puede ser null, en el caso de que no se especifiquen datos de
     * inicio; o algunos elementos pueden ser nulos, indicando que no hay datos
     * iniciales para esos campos en particular.
     * @param titulo el titulo del formulario
     *
     * @return un array de valores correspondientes a los campos mostrados, o
     * null si el usuario cancela la operación.
     */
    public static String[] mostrarFormulario(Component origen, String[] campos, String[] valoresIniciales, String titulo) {
        // Instancia de Formulario
        Formulario formulario = new Formulario(campos, valoresIniciales);
        // Creación de objeto JDialog donde se alojará el formulario
        JDialog dialog = formulario.createDialog(origen, titulo != null?titulo:"Formulario");
        // Se agrupan los elementos visuales en la ventana
        dialog.pack();
        // Se muestra la ventana en la pantalla
        dialog.setVisible(true);

        //si el usuario cancela, se retorna null
        if(!formulario.aceptar) return null;
        // Se extraen los datos ingresados por el usuario
        String[] datos = new String[campos.length];
        for (int i = 0; i < campos.length; i++) {
            datos[i] = formulario.camposFormulario[i].getText();
        }
        return datos;
    }

    /**
     * Método para abrir un cuadro de diálogo solicitando varios elementos de
     * entrada de datos.
     *
     * @param origen el componente de interfaz gráfica a donde se mostrará el
     * formulario
     * @param campos los campos de captura que se mostrarán en el formulario
     * @param titulo el titulo del formulario
     *
     * @return un array de valores correspondientes a los campos mostrados, o
     * null si el usuario cancela la operación.
     */
    public static String[] mostrarFormulario(Component origen, String[] campos, String titulo) {
        // Llamada a método
        return mostrarFormulario(origen, campos, null, titulo);
    }

    /**
     * Método para abrir un cuadro de diálogo solicitando varios elementos de
     * entrada de datos.
     *
     * @param origen el componente de interfaz gráfica a donde se mostrará el
     * formulario
     * @param campos los campos de captura que se mostrarán en el formulario
     * @param valoresIniciales los valores iniciales para cada elemento. Este
     * parámetro puede ser null, en el caso de que no se especifiquen datos de
     * inicio; o algunos elementos pueden ser nulos, indicando que no hay datos
     * iniciales para esos campos en particular.
     *
     * @return un array de valores correspondientes a los campos mostrados, o
     * null si el usuario cancela la operación.
     */
    public static String[] mostrarFormulario(Component origen, String[] campos, String[] valoresIniciales) {
        // Llamada a método
        return mostrarFormulario(origen, campos, valoresIniciales, null);
    }

    /**
     * Método para abrir un cuadro de diálogo solicitando varios elementos de
     * entrada de datos.
     *
     * @param origen el componente de interfaz gráfica a donde se mostrará el
     * formulario
     * @param campos los campos de captura que se mostrarán en el formulario
     *
     * @return un array de valores correspondientes a los campos mostrados, o
     * null si el usuario cancela la operación.
     */
    public static String[] mostrarFormulario(Component origen, String[] campos) {
        // Llamada a método
        return mostrarFormulario(origen, campos, null, null);
    }

    /**
     * Método constructor para todos los métodos decladarados en la clase
     * @param campos los campos de captura que se mostrarán en el formulario
     * @param valoresIniciales los valores iniciales para cada elemento. Este
     * parámetro puede ser null, en el caso de que no se especifiquen datos de
     * inicio; o algunos elementos pueden ser nulos, indicando que no hay datos
     * iniciales para esos campos en particular.
     */
    private Formulario(String[] campos, String[] valoresIniciales) {
        // Llamada al constructor padre
        super();

        // Remueve los elementos visuales del formulario
        removeAll();

        // Establece el diseño del formulario
        setLayout(new GridLayout(campos.length + 1, 2,5,5));
        this.camposFormulario = new JTextField[campos.length];
        for (int i = 0; i < campos.length; i++) {
            add(new JLabel(campos[i]));
            this.camposFormulario[i] = new JTextField(COLUMNAS);
            add(this.camposFormulario[i]);
            if(valoresIniciales != null && valoresIniciales[i] != null){
                this.camposFormulario[i].setText(valoresIniciales[i]);
            }
        }

        JPanel panelBtnOk = new JPanel();
        JButton btnAceptar = new JButton("Aceptar");
        panelBtnOk.add(btnAceptar);
        add(panelBtnOk);

        JPanel panelBtnCancelar = new JPanel();
        JButton btnCancelar = new JButton("Cancelar");
        panelBtnCancelar.add(btnCancelar);
        add(panelBtnCancelar);

        btnAceptar.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e){
                aceptar = true;
                getTopLevelAncestor().setVisible(false);
            }
        });

        btnCancelar.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e){
                getTopLevelAncestor().setVisible(false);
            }
        });
    }
}

private static String toJSON(Object object) {
    if (object instanceof Map) {
        Map map = (Map) object;

        StringBuilder builder = new StringBuilder("{");

        boolean first = true;

        for (Object key : map.keySet()) {
            if (!first) builder.append(",");
            builder.append(String.format("\"%s\": %s", key, toJSON(map.get(key))));

            first = false;
        }

        builder.append("}");

        return builder.toString();

    } else if (object instanceof List) {
        List list = (List) object;

        StringBuilder builder = new StringBuilder("[");

        for (int i = 0; i < list.size(); i++) {
            if (i > 0)
                builder.append(",");

            builder.append(toJSON(list.get(i)));
        }

        builder.append("]");

        return builder.toString();

    } else if (object instanceof Number || object instanceof Boolean) {
        return object.toString();

    } else if (object instanceof String) {
        return String.format("\"%s\"", ((String) object).replaceAll("\"", "\\\""));

    } else if (object == null) {
        return "null";

    } else {
        throw new IllegalArgumentException("ERROR");
    }
}