Java + Swing 018. Modo diseño en NetBeans. Agregar JComboBox y JCheckBox a un jTable.

Ejercicio: Realizar una pequeña aplicación que permita agregar JComboBox y JCheckBox a una tabla, dentro de una columna específica. La aplicación debe permitir eliminar, mover y editar cada fila de la tabla.
Diseño de formulario con JFrame.
En la imagen podemos ver el diseño y los nombres de variables de cada objeto, es importante para que se ajuste a los métodos que se crean. Se puede cambiar el “Nombre de variable” de cada objeto haciendo clic derecho y “Cambiar nombre de variable…”. Es fácil distinguir cual corresponde a cada objeto, los nombre de variables son iguales a la etiqueta asignada al objeto.
Observación: Tomar en cuenta que hay que utilizar las importaciones “import”, básico para utilizar ciertos métodos y objetos. El “setLocationRelativeTo(null)” sirve para centrar el formulario. Los métodos llamados en el constructor de la clase se inician al ejecutar el formulario. Las variables de clase se pueden llamar desde cualquier método, por tanto se utiliza para objetos que se necesitan utilizar en varias ubicaciones.
Creamos los métodos siguientes en el apartado “Fuente”. Estos métodos utilizan conversiones de tipos de datos, controles de excepciones y demás para controlar lo mejor posible el resultado. Se agregan comentarios para tratar de facilitar el entendimiento del funcionamiento de cada código.
Código Java
private void tableModel(){
//Metodo para configurar el DefaultTableModel.
//Se llama desde el constructor del JFrame para que la tabla arranque con el
//formato deseado.
//Indicamos el tamaño de las columnas.
jTable1.getColumnModel().getColumn(0).setPreferredWidth(5);
jTable1.getColumnModel().getColumn(1).setPreferredWidth(100);
jTable1.getColumnModel().getColumn(2).setPreferredWidth(100);
jTable1.getColumnModel().getColumn(3).setPreferredWidth(100);
jTable1.getColumnModel().getColumn(4).setPreferredWidth(100);
jTable1.getColumnModel().getColumn(5).setPreferredWidth(5);
//Asigamos a la variable model el objeto jTable1.
//Esto permite utilizar la variable model para trabajar con la tabla.
model = (DefaultTableModel)jTable1.getModel();
//Indicamos que al principio tendrá cero filas.
model.setNumRows(0);
}
private void arranque(){
//Desactivamos estos botones al arranque.
subir.setEnabled(false);
bajar.setEnabled(false);
}
private void limpiar(){
//Permite poner a cero las filas del jTable1
model.setNumRows(0);
arranque();
}
private void agregar(){
//Método par agregar filas al jTable1.
//Cada fila tendrá también un JComboBox y un JCheckBox.
//Declaramos un nuevo objeto JComboBox.
JComboBox combo = new JComboBox();
//Le asiganamos dos valores.
combo.setModel(new DefaultComboBoxModel(new Object[]{
"Masculino","Femenino"
}));
//Indicamos que vaya seleccionado por defecto el primer valor, para esto
//utilizando el setSelectedIndex y como parémetro el índice del valor.
//El índice empieza de cero, por tanto le corresponde al primer valor.
combo.setSelectedIndex(0);
//Obtenemos el valor seleccionado como String.
String toString = combo.getSelectedItem().toString();
//Creamos un objeto JCheckBox.
JCheckBox check = new JCheckBox();
//Forma en la que daremos valor a la columna id.
int id = jTable1.getRowCount() + 1;
//Utilizamos el model para agregar la fila, el valor de la columna que corresponde
//al JCheckBox debe ser de tipo boolean, el del JComboBox tipo String.
model.addRow(new Object[]{
id,"","",toString,"", false});
//Utilizamos el CellEditor para agregar el JComboBox y el JCheckBox.
//Para el JCheckBox también utilizamos el CellRenderer que nos permitirar tener dibujado el objeto.
jTable1.getColumnModel().getColumn(3).setCellEditor(new DefaultCellEditor(combo));
jTable1.getColumnModel().getColumn(5).setCellEditor(new DefaultCellEditor(check));
//Como parámetro para el CellRenderer le pasamos una clase que se crea más adelante.
//Es una clase predefinida con métodos predefinidos.
jTable1.getColumnModel().getColumn(5).setCellRenderer(new Render_CheckBox());
jTable1.repaint();
}
public void seleccion(){
//Método para activar y desactivar los botones "subir" y "bajar" según corresponda.
if(jTable1.getRowCount() > 0){
int selectedRow = jTable1.getSelectedRow() + 1;
int inferior = 1;
int superior = 1;
for (int i = 0; i < jTable1.getRowCount(); i++) {
superior = i + 1;
}
if(inferior == jTable1.getRowCount()){
subir.setEnabled(false);
bajar.setEnabled(false);
}
else{
if(selectedRow == inferior){
subir.setEnabled(true);
bajar.setEnabled(false);
}
else{
if(selectedRow == superior){
bajar.setEnabled(true);
subir.setEnabled(false);
}
else{
subir.setEnabled(true);
bajar.setEnabled(true);
}
}
}
}
}
private void removerSelec(){
//Este método nos permitiré eliminar una o varias filas que tengan el JCheckBox
//en true o seleccionado.
try {
if(jTable1.getRowCount() > 0){
for (int i = 0; i < jTable1.getRowCount(); i++) {
//Forma de obtener el valor boolean de la columna indicada.
boolean res = Boolean.valueOf(model.getValueAt(i, 5).toString());
while (res) {
model.removeRow(i);
res = false;
orden();
}
}
}
//El try es para controlar posibles errores, en caso de darse alguno el programa no
//realiza ninguna acción.
} catch (Exception e) {

}

}
public void moverArriba(){
//Método asignado al botón subir.
//Nos permitira mover una fila arriba utilizando moveRow
//El primer parámetro indica desde, el segundo hasta y tercero donde.
try {
int selc = jTable1.getSelectedRow();
int mov = jTable1.getSelectedRow() + 1;
model.moveRow(selc, selc, mov);
//Abajo como se explica en la documentación.
//public void moveRow(int start, int end, int to)
//start - the starting row index to be moved
//end - the ending row index to be moved
//to - the destination of the rows to be moved
//El método orden nos permitirá reescribir el orden del id.
orden();
seleccion();
jTable1.repaint();
} catch (Exception e) {
jTable1.repaint();
}

}
public void moverAbajo(){
//Método asignado al botón bajar.
//Similar el funcionamiento al método moverArriba().
try {
int selc = jTable1.getSelectedRow();
int mov = jTable1.getSelectedRow() - 1;
model.moveRow(selc, selc, mov);
orden();
seleccion();
jTable1.repaint();
} catch (Exception e) {
jTable1.repaint();
}

}
public void orden(){
//Método para reescribir el orden del id.
for (int i = 0; i < jTable1.getRowCount(); i++) {
model.setValueAt(i + 1, i, 0);
}
}
//Clase predefinida que hereda de un JCheckBox e implementa el TableCellRenderer.
//La clase está predefinida. Copia del blog de jc-mouse.
class Render_CheckBox extends JCheckBox implements TableCellRenderer {
//
private JComponent component = new JCheckBox();

/** Constructor de clase */
public Render_CheckBox() {
setOpaque(true);
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
//Color de fondo de la celda
( (JCheckBox) component).setBackground( new Color(98,138,183) );
//obtiene valor boolean y coloca valor en el JCheckBox
boolean b = ((Boolean) value).booleanValue();
( (JCheckBox) component).setSelected( b );
return ( (JCheckBox) component);
}
}
Utilizamos el evento “ActionPerformed” para llamar los métodos desde los botones. Se utiliza el evento “MouseClicked” para el jTable. Para utilizar un “Evento” hacemos clic derecho sobre el objeto y seleccionamos “Eventos” de la lista utilizamos la que podamos aplicar al objeto. En la mayoría de los casos se utiliza el “ActionPerformed”. Se agregan comentarios para tratar de facilitar el entendimiento.
Código Java
    private void agregarActionPerformed(java.awt.event.ActionEvent evt) {                                        
//Método botón agregar.
agregar();
}

private void limpiarActionPerformed(java.awt.event.ActionEvent evt) {
//Método botón limpiar.
limpiar();
}

private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
//Método para el jTable 1, obtener fila seleccionada.
seleccion();
}

private void eliminarActionPerformed(java.awt.event.ActionEvent evt) {
//Método botón eliminar.
removerSelec();
}

private void subirActionPerformed(java.awt.event.ActionEvent evt) {
//Método botón subir.
moverArriba();
}

private void bajarActionPerformed(java.awt.event.ActionEvent evt) {
//Método botón bajar.
moverAbajo();
}
Por último tenemos el formulario en ejecución.

18 comentarios :

  1. Amigo muchas gracias por este gran aporte es justo lo que necesitaba.
    Gracias

    ResponderEliminar
  2. Gracias por comentar, espero que los materiales te sean de utilidad. Saludos.

    ResponderEliminar
  3. Amigo tanto los comentarios y el código me han servido mucho.. si no es mucho pedirte podrías hacer un post donde se pueda insertar un jCheckBox dentro de jComboBox te lo agradecería mucho.

    ResponderEliminar
  4. Que tal amigo, voy a ver qué puedo hacer con el pedido específico, si hay posibilidad lo subo. Gracias por comentar.

    ResponderEliminar
  5. hola amigo nueva mente pasando por tu blog y para hacerte una pequeña consulta.
    estoy realizando una aplicación java con el IDE Netbeans 7.4 pero me a surgido el siguiente problema parameter index out of range (1 > number of parameters, which is 0) no se a que se debe ya que cuando realizo un registro nuevo el guarda sin ningún problema en la base de datos MySQL y lo actualiza sin problemas a su vez el proble se presenta cuando quiero eliminar ese registro te agradecería tu ayuda y espero pronto una respuesta de tu parte.

    ResponderEliminar
  6. Buenos días amigo, yo suelo trabajar con Hibernate como intermediario entre mi aplicación y la base de datos, no suelo utilizar sentencias SQL. Lo que puedo pensar según el mensaje de error que describes, es que el parámetro que le pasas para hacer la eliminación del registro no se corresponde o no se encuentra. Si utilizas una llave primaria para eso, deberías ver si tu código de eliminación de registro pasa correctamente el parámetro. Espero te sea de ayuda.

    ResponderEliminar
  7. Buenos días amigo gracias por tu sugerencia eh captado tu mensaje y ya pude solucionar el problema que tenia pues yo no uso Hibernate aun ya que apenas estoy empezando en el desarrollo de aplicaciones pero aun futuro trabajare con el es bueno saber que puedo contar con tu ayuda nuevamente gracias.

    ResponderEliminar
  8. Hola amigo quiero pedirte un gran favor, es que nuestro profesor de programación nos a pedido hacer un pequeño proyecto donde se pueda leer un directorio que contengo imágenes en el y mostrar esas imágenes en jtable eh buscado por toda la web y no eh conseguido nada te pido por favor me ayudes con esto te agradecería mucho por este gran favor espera una respuesta de tu parte.

    ResponderEliminar
    Respuestas
    1. Suena interesante el trabajo Luis, voy a ver qué puedo hacer en el tiempo libre que tengo. Antes pediste un código para insertar un jCheckBox dentro de jComboBox, no le encontré aplicación útil por eso no le dedique tiempo para ver. Este último seguro que se puede. Saludos.

      Eliminar
    2. Que tal, puedes consultar este bloc -->( http://goo.gl/uKrT2W ) es funcional la aplicación que desarrolla para manejar imágenes en jTable, en estos día subiré una que se basa esos código. Saludos.

      Eliminar
  9. Hola amigo ya pude resolver el problema de las imágenes en el jtable llevándolo desde el directorio me gustaría facilitarte el código para que lo estudies pero al mismo tiempo pedirte otra consulta pues me gustaría saber como capturo el valor de un jcombobox estático es decir yo creo un método el cual siempre lo llamo LlenarComboEstatico el ejemplo seria de la siguiente forma..
    public void LlenarComboEstatico () {
    jComboBox1.addItem("");
    jComboBox1.addItem("Item1");
    jComboBox1.addItem("Item2");
    jComboBox1.addItem("Item3");
    jComboBox1.addItem("Item");
    }
    el asunto es como hacer para que solo me tome el numero uno y en caso que no contenga numero capture un cero me gustaría saber si esto es posible agradezco tu respuesta amigo y muchas gracias por siempre responder a mis dudas.

    ResponderEliminar
    Respuestas
    1. Estas son las formas habituales de obtener datos de un jComboBox.
      El primero retorna un Object pasando como parámetro el índice correspondiente, en este caso el “0” será el primer elemento, “1” el segundo y así según la cantidad de elementos. Para filtrar los datos seguramente la forma más fácil es usar condicionales. Espero que te sea útil.
      Object itemAt = jComboBox1.getItemAt(0);
      Retorna el índice del elemento seleccionado.
      int selectedIndex = jComboBox1.getSelectedIndex();
      Retorna el valor del elemento seleccionado.
      Object selectedItem = jComboBox1.getSelectedItem();
      Retorna un array de objetos con los elementos seleccionados.
      Object[] selectedObjects = jComboBox1.getSelectedObjects();

      Eliminar
  10. Hola amigo Carlos gracias por toda la ayuda brindada me ha sido muy útil pero cada que termino algo surgen nuevas ideas y una de esas es la que te comentare ya que eh terminado mi aplicación quiero generar el instalador de ella pero a la ves hacer una versión beta de la aplicación como podría lograr eso te estaría nuevamente agradecido si me ayudas con esto.
    Y de paso te dejo este ejemplo donde puedes leer un directorio desde java y mostrar las imagen en un jtable quizás te sea de ayuda en un futuro.
    https://mega.co.nz/#!15kgVYRZ!pm9ZVem2uffcytSPVYSvx_PN2VxBfipkr5TCRl8djCA

    ResponderEliminar
    Respuestas
    1. Que tal amigo, en una de las entradas del bloc que se titula “Compilando Proyecto” hay un ejemplo que te puede servir para generar un JAR de tu proyecto, en lo de crea un instalador dependería de que tan grande es el proyecto. Gracias por compartir el enlace, le daré un vistazo. Hace días atrás pude subir un ejemplo para trabajar con imágenes en JTable, el 25 de Swing con NetBeans. Un saludos y gracias por tus comentarios.

      Eliminar
  11. hola amigo primero que todo quiero darte las gracias por toda la ayuda que me haz brindo me a sido muy util, en esta ocacion quiero pedirte nuevamente que me ayudes ya que tengo un pequeño problema en la aplicacion que estoy realizan, el problema es el siguiente:
    tengo un formulario el cual utilizo para actualizar los stock, se que usted no usa consultas Sql pero mi proble esta en que la consulta esta bn pero cuando ya lo hago desde el formulario y actualizo un stock es decir si tengo 2 stock y actualizo ese stock ingresando 1 desde el formulario lo mas logico es que ya serian stock pero lo que hace es duplicarme ese stock en ves de 3 coloca 4 y asi sucesivamente aqui te envio el metodo que utilizo para actualizar mis stocks

    public synchronized void UPDATE_STOCK(Connection con, String cod) throws SQLException{
    PreparedStatement pst = con.prepareStatement("UPDATE par_productos SET pr_codigo = ?, pr_cantidad = pr_cantidad + ? WHERE pr_codigo = '"+cod+"'");
    pst.setString(1, getPr_codigo());
    pst.setInt(2, getPr_cantidad());
    pst.executeUpdate();
    }

    y ese es el boton donde invoco al metodo para que me actualice los stock te agredesco mucho y me ayudes con este pequeño problema amigo

    private void Cmb_GuardarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Cmb_GuardarActionPerformed
    try {
    Frm_SPLASH.PRO.setTodos(Txt_Codigo.getText(),
    Integer.valueOf(Txt_StockActual.getText()));
    if (sw == 0) {

    }else{
    Frm_SPLASH.PRO.UPDATE_STOCK(Frm_SPLASH.CN.getConnection(), cod);
    formInternalFrameOpened(null);
    }
    } catch (SQLException | NumberFormatException e) {
    JOptionPane.showMessageDialog(null, e.getMessage());
    }
    }

    ResponderEliminar
    Respuestas
    1. Que tal amigo, no soy muy bueno en SQL, no sé si te pueda ayudar, pero lo que puedo intuir es que el nombre del campo “cantidad” (pr_cantidad = pr_cantidad + ?) puede que este ocultando alguna variable clase o local. Lo mejor es no igualar los nombres de objeto del formulario con los nombres de campos de la tabla. El código se ve muy bien estructurado. Es lo que puedo aportar amigo, gracias por comentar tu duda.

      Eliminar
    2. hola amigo no había visitado tu blog xq me ocupe un poco con los exámenes de a universidad pero ya estoy de vuelta quiero hacerte una consulta como hago para dar privilegios de usuarios a mi aplicación ya q eh estado buscando x la web y no eh podido conseguir nada útil te agradezco tu ayuda.

      Eliminar
    3. Que tal amigo, la forma habitual es crear un formulario en la que se pueda registrar nuevos usuarios, creando una tabla para almacenarlas y otro formulario para permitir el acceso de esos usuarios. Seria lo habitual, con nombre de usuario y contraseña de acceso. No tengo ningún ejemplo simple para subir. Espero te sea de utilidad. Gracias por comentar.

      Eliminar