🙂 Una de las preguntas más buscadas por programadores java es la de crear componentes swing en tiempo de ejecución, eso no es difícil y la respuesta bastante obvia, sin embargo la mayoría se tranca en darle alguna utilidad al control creado, por ejemplo, para crear un JButton en tiempo de ejecución (el ejemplo más común), basta con las siguientes líneas de código:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { JButton boton = new JButton("Soy un boton"); boton.setVisible(true); boton.setSize(100,45); this.add(boton); this.validate(); }
Colocando estas lineas dentro un JButton, cada vez que sea presionado, añadirá un nuevo botón al contenedor, ahora para darle un poco de utilidad, se debe añadir al botón que se crea un ActionListener y escribir las lineas de código que se ejecutaran cuando el usuario interactue con el botón creado en tiempo de ejecución.
Bonito ejemplo, sencillo, pero no nos sirve, no para los que quieren hacer algo más elaborado, y con pocas lineas de código, así que mejor hagamos las cosas interesantes, en este post crearemos un swing en tiempo de ejecución al cual le añadiremos un ActionListener y su evento correspondiente, sin embargo para variar un poco de los ejemplos de la red, el componente que añadiremos sera un componente previamente diseñado por nosotros.
Como se ve en la imagen, nuestro programa consta de un botón al cual, cada vez que sea presionado, añade un componente que esta formado por un JPanel como contenedor, el cual alberga a un jlabel, un jTextField y un JButton, cuando este JButton sea presionado, obtendrá el valor que esta en el JTextField y lo muestra en un JOptionPane, se puede ver también la palabra «key_3» este es un identificador único para cada objeto dinámico que creamos y se va llenando de acuerdo al orden de creación, es decir key_1, jey_2, key_3….key_n, en nuestro ejemplo presionamos el botón 3.
Ok, creo que se entiende lo que queremos hacer, así que empecemos.
Necesitamos
Proyecto.
1. Crea un nuevo proyecto en Netbeans. Añade un JFrame (nombre: interfaz.java), una clase (nombre: jcPanel.java) y un JPanel (jpComponente.java), es decir:
Proyecto -- Main.java -- interfaz.java -- jcPanel.java -- jpComponente.java
Está sera nuestra estructura de trabajo. Continuemos
2. Lo primero sera diseñar nuestro componente dinámico. Abre el JPanel: jpComponente y añade los siguientes controles:
Dirígete al codigo «Source» y modifica el constructor de clase de la siguiente manera:
//ANTES public jpComponente() { initComponents(); } //DESPUES public jpComponente( int index ) { initComponents(); //JPanel setBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED)); this.setSize(230, 30); this.setVisible(true); //se agrega un comando al boton this.btn.setActionCommand("key_" + index); }
Para terminar el componente, debemos modificar la propiedad PRIVATE de los objetos JButton: btn y JTextField: txtName que netbeans nos crea por defecto, por la de PUBLIC, para hacer esto, en el JButton realiza clic derecho y dirígete a PROPIEDADES, después ve a la pestaña CODIGO, donde dice «Modificadores de variable: private […]», clic en el botón con puntos suspensivos, aparece una pequeña ventana, ahí, en el combo que dice «Acceso«, escoge la opción PUBLIC y le das ACEPTAR -> CERRAR, repite los mismos pasos para el JTextfield.
3. Abre ahora la clase jcPanel y pega el código:
import java.awt.Color; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.swing.BorderFactory; import javax.swing.JOptionPane; import javax.swing.JPanel; /** * @web https://www.jc-mouse.net * @author Mouse */ public class jcPanel extends JPanel implements ActionListener { private int index = 1; //Nos sirve para almacenar a los objetos creados private Map nota = new HashMap(); public jcPanel() { this.setSize(300, 400); this.setVisible(true); this.setBorder(BorderFactory.createLineBorder( Color.BLACK )); this.setLayout( new FlowLayout() ); } public void Mi_Componente() { //instancia nueva a componente jpComponente jpc = new jpComponente(index); jpc.btn.addActionListener(this);//escucha eventos this.add(jpc);//se añade al jpanel this.validate(); //se añade al MAP this.nota.put("key_" + index, jpc ); //se incrementa contador de componentes index++; } public void actionPerformed(ActionEvent e) { //se obtiene el comando ejecutado String comando = e.getActionCommand(); //se recorre el MAP Iterator it = nota.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); //se obtiene el KEY -> identificador unico String itm = entry.getKey().toString(); //si comando de componente es igual a comando pulsado if( itm.equals(comando)) { //se recupera el contenido del JTextfield String name = ((jpComponente) entry.getValue()).txtName.getText(); //mostramos resultado JOptionPane.showMessageDialog(null, "Se presiono boton " + itm + " \n Hola " + name); } } } }
Explicación: Lo que hacemos en esta clase es extender de un JPanel e implementar el ActionListener, lo primero es para tener un JPanel personalizado donde agregar los controles dinámicos, los segundo para escuchar los eventos del usuario sobre los controles.
El método llamado «Mi_componente()», creara un nuevo jcComponente, le añade un addActionListener y lo coloca al contenedor, al mismo tiempo hacemos uso de un MAP donde tambien se añadira el componente y aquí lo importante, el key_n (identificador único), para llevar un control de los controles creados se utiliza una variable de tipo entero llamado «index«. Tenemos tambien el método actionPerformed, este metodo propio del ActionListener, nos permite gestionar los eventos de cada uno de los controles creados, cada boton dentro del jpComponente cuenta con un actioncomand, cuando se presiona un botón recorremos el MAP y buscamos el comando que corresponda, cuando lo encontramos extraemos el componente y ya podemos manipularlo como queramos, para este ejemplo, extraemos el contenido del JTextField: txtName y lo mostramos junto al Key_n en un JOptionPane.
4. Para terminar implementamos todo esto en la clase interfaz.java, pero primero, a la interfaz le añadimos un JButton y le damos un tamaño como para que entre nuestro JPanel: jcPanel.
Ahora implementamos nuestra clase jcPanel, añadimos al JFrame y colocamos el evento pata el JButton
01 jcPanel mi_panel = new jcPanel(); 02 03 /** Creates new form interfaz */ 04 public interfaz() { 05 initComponents(); 06 //se añade componente al JFrame 07 this.add(mi_panel); 08 //posicion del panel para no sobreponer al boton 09 this.mi_panel.setLocation(10, 50); 10 } 11 12 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 13 mi_panel.Mi_Componente(); 14 }
FIN
Ejecuta 🙂
Descargar Proyecto Controles dinámicos
Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.
Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye
Enjoy! :)
Continuación del tutorial «Utiliza 2 bases de datos diferentes en una aplicación» La Interfaz frmSelected.java: Haciendo...
Para ponerse a tono con el ambiente mundialista de Brasil 2014, en este post construiremos un swing java al que llamarem...
Cuando se desarrolla una aplicación, puede ser un requisito que este tenga soporte para varias tipos de base de datos, s...
Microsoft el gigante de la tecnología está tratando de hacer que Python sea más fácil de comprender para aquellos intere...
La página oficial de Retrofit, se describe así misma como «Un cliente REST seguro para Android y Java». Y es así, ya qu...
En este tutorial utilizaremos la librería PHPMailer para enviar correo electrónico utilizando el servidor de GMail de Go...
Los comentarios estan cerrados
El gigante tecnologico Google a puesto un bonito Doodle en su buscador que esta fascinando a sus millones de usuarios qu...
WhatsApp anuncio a través de su blog que ya se encuentra disponible la función de envío de fotos y videos TEMPORALES, es...
Muchas de las innovaciones computacionales de la NASA se desarrollaron para ayudar a explorar el espacio, pero ahora la...
TikTok es una plataforma de microvideos muy popular entre los jóvenes el cual cuenta ya con millones de videos cortps de...
Excelente ejemplo, muy bien elaborado.
Me lleve bastante tiempo encontrar un ejemplo de este tipo y es la única web que verdaderamente se acerco a la generación de objetos en tiempo de ejecución.
Salu2
Muy bien amigo, me salvaste. Comenzaré a seguirte y a ver este blog más seguido. Muy bien !!
Aprovechando, como le pondrias un scrollbar para ver los elementos que se van agregando despues del tamaño del panel que se genera mi_panel
te la sabes xD me sirvio de mucho
Gracias bro!! estaba buscando exactamente esto y me ayudaste de mucho!!!
Matt:
«Aprovechando, como le pondrias un scrollbar para ver los elementos que se van agregando despues del tamaño del panel que se genera mi_panel»
Lo mismo ke el.
Tiene un bug, cuando creas elementos (por primera vez) y presionas un boton Ok, obtiene bien el valor.
Pero cuando creas más elementos despues de presionar el Ok, y vuelves a presionar Ok ya no obtiene el texto del input deseado, adquiere el texto por defecto.
Holas! buenisimo tu ejemplo…queria hacer una consulta, suponiendo que cree un boton personalizado que extienda de JButton, y solo le agrego que el nombre a mostrar sea «SALIR»… cada vez que que lo agregue a un formulario saldría con ese nombre.Hay alguna manera de hacer que si modifico el componente original, se actualice en todos los formularios? por ejemplo si cambio el nombre por «EXIT» que se actualice en todos lados. Muchas Gracias!
Gracias, me fue de mucha ayuda.
Hola que tal, tu ejemplo se ve de maravilla, solo que deseo aplicar esta forma en un JScrollPane, ¿hay alguna forma de poder hacerlo?
Hola, buenas tarde esta bien la creación de estos componentes en tiempo de ejecución.
Pero no hay una manera de que se puedan guardar una vez que se hayan creado en tiempo de ejecución?
tendrías que serializarlos