Inicio > Programación > JTable “dinámico” en NetBeans

JTable “dinámico” en NetBeans

18 noviembre, 2009 Deja un comentario Go to comments

Al utilizar NetBeans y colocar algún JTable en la interfaz gráfica de usuario suele ser un problema el poder agregar filas a medida que se van necesitando.
Esto se debe a que los JTable no tienen un método para controlar la creación y eliminación de sus filas. Investigando un poco uno descubre que esto se hace utilizando el modelo (TableModel) del objeto JTable. y supone que puede accederlo (a un puntero del modelo) por medio del método getModel() de JTable.
El problema es que aún accediendo al modelo de la tabla, no es posible agregar o eliminar filas como uno esperaría.

La solución más sencilla (y la peor) es asignar por medio del editor de NetBeans una cantidad “estimada” de filas para la tabla. Si llegan a ser demasiadas, el uso de memoria del programa se vuelve exagerado y hay que modificar los parámetros de la JVM para iniciar el programa con la consecuente pérdida de rendimiento. En pocas palabras es lo más ineficiente que se puede hacer.

Una solución muchísimo mejor que también es fácil de implementar es declarar el modelo que va a utilizar la tabla como cualquier otro atributo de la clase (para poder ser utilizado con un JTable agregado gráficamente).

private DefaultTableModel modeloTabla;

Luego este modelo se debe instanciar e inicializar (en el constructor). Pero esto tiene que ser antes de la llamada al método initComponents() que genera NetBeans. De lo contrario este método intentará asignar un modelo no instanciado al JTable, provocando un IllegalArgumentException.

modeloTabla = new DefaultTableModel();
// Agregar las columnas que se necesiten utilizando el método
// addColumn(Object columnName) de DefaultTableModel.
// También es posible utilizar un constructor sobrecargado
// que recibe como parámetros un vector Object[] { … } cuyos
// elementos son los nombres de las columnas y un int con la
// cantidad inicial de filas (se crean vacías):
// DefaultTableModel(new Object[] { "Col 1", "Col 2" }, 5)
initComponents();

Lo que sigue es asociar este modelo al JTable agregado gráficamente. Para hacer esto se selecciona el JTable, y en sus propiedades se busca “model”.

 
En la ventana que aparece al presionar el botón para editar la propiedad se selecciona “Custom code” en el combo box y en el campo de texto simplemente se coloca el nombre del objeto modelo definido en el código.

 
Después sólo es cuestión de agregar, eliminar o incluso mover las filas cuando sea necesario, directamente en el modelo.

// Agregar fila, el parámetro es un vector con los valores de
// las columnas

modeloTabla.addRow(Object[] rowData);

// Eliminar fila, el parámetro es el índice de la fila a
// eliminar

modeloTabla.removeRow(int row);

// Eliminar todas las filas
modeloTabla.getDataVector().clear();

// Mover una o varias filas, los primeros dos parámetros
// seleccionan la(s) fila(s) que se va(n) a mover y el tercero
// indica la posición hacia donde se va a mover dicha selección

modeloTabla.moveRow(int start, int end, int to);

Los cambios se reflejan instantáneamente en el JTable.

Categorías: Programación
  1. Francisco
    26 noviembre, 2009 a las 15:22

    iuhui uhiuh ihiuh h hiihih

  2. Manuel
    15 marzo, 2010 a las 12:14

    Gracias por tus instrucciones me han servido mucho.

  3. Antonio
    8 noviembre, 2010 a las 08:05

    Al ejecutar el proyecto me da error en «jTable1.setModel(modelo)»; sabes de que puede ser?

    Gracias

    • 8 noviembre, 2010 a las 08:13

      Podría ser que el modelo o el JTable tengan un identificador diferente al usado. Sería mejor si indicaras qué dice el error.

    • robertdilan
      2 junio, 2016 a las 00:14

      Podria ser que te faltaq importar alguna libreria de DefaultTable y si no mejor muestra tu error para aydarte con mas presicion

  4. Antonio
    8 noviembre, 2010 a las 17:09

    El identificador es el mismo, el error que me da es este:

    GRAVE: Application class tablas.tablasApp failed to launch
    java.lang.RuntimeException: Uncompilable source code
    at tablas.JtablasView.initComponents(tablasView.java:154)
    at tablas.tablasView.(tablasView.java:73)
    at tablas.tablasApp.startup(tablasApp.java:19)

    • 8 noviembre, 2010 a las 17:51

      Al parecer es un error de compilación dentro del método initComponents() que genera NetBeans. Te recomiendo expander el código de ese método y revisar el mensaje de error de esa línea (154).

      • Antonio
        9 noviembre, 2010 a las 14:21

        El error de la línea 154 es el «jTable1.setModel(modelo);» que está dentro del initComponets(), no sé porque sale porque no tengo ningún otro error en el código.

      • 9 noviembre, 2010 a las 15:56

        Al colocar el cursor sobre la línea con el error y presionar Alt+Enter NetBeans muestra un mensaje que describe por qué es.

  5. Antonio
    9 noviembre, 2010 a las 16:31

    Ya está, lo tenía declarado donde no tocaba, siento mucho las molestas y muchísimas gracias por la ayuda.

    • 9 noviembre, 2010 a las 19:04

      No hay problema, qué bueno que hallaste la solución.

  6. DIego Armando
    18 noviembre, 2010 a las 21:34

    hola amigo oye tengo un problemota espero me puedas ayudar, no me marca ningùn error ni nada, simplemente no me aparece ninguna tabla, mi codigo es el siguiente:
    public class RentasClientes extends javax.swing.JInternalFrame {

    /** Creates new form RentasClientes */
    public RentasClientes() {
    Object[][] data = {
    {«Mary», «Campione»,
    «Esquiar»},
    {«Lhucas», «Huml»,
    «Patinar»},
    {«Kathya», «Walrath»,
    «Escalar»},
    {«Marcus», «Andrews»,
    «Correr»},
    {«Angela», «Lalth»,
    «Nadar»}
    };
    String[] columnNames = {«Nombre»,
    «Apellido»,
    «Pasatiempo»,
    };
    DefaultTableModel tabla = new DefaultTableModel(data,columnNames);

    initComponents();

    }

    gracias de antemano espero me puedas ayudar

    • 18 noviembre, 2010 a las 21:44

      Creo que es porque estás declarando el modelo dentro del constructor. Así el objeto es una variable que sólo existe mientras se ejecuta el constructor.
      La solución es declarar el modelo como un atributo de la clase y usar el constructor sólo para instanciarlo.

  7. 12 febrero, 2011 a las 10:46

    Gracias, es justo lo que yo estaba buscando. Muchas Gracias!

  8. abde
    16 febrero, 2011 a las 18:53

    Muchas gracias!!!!!!! buena ayuda!!!!!

  9. Paula
    3 marzo, 2011 a las 06:30

    Hola, intento agregarle un evento «mouseClicked» pero no funciona… es posible hacerlo?? gracias!!

  10. Temo
    7 abril, 2011 a las 08:23

    De gran ayuda

  11. Adrian
    23 abril, 2011 a las 21:36

    Gracias :D. Ya me estaba desesperando. :D

  12. pako
    26 abril, 2011 a las 14:25

    Felicidades me sacaste de un apuro ya me estaba desesperando mucho muchas gracias.

  13. 17 junio, 2011 a las 13:15

    Un saludo espero me puedas ayudar.
    El problema es que yo tengo que tener un formulario para agregar a mis clientes, y guardarlos en una matriz: clientes[30][5], cada ves que le doy un click va llenando

    public class frmcliente extends javax.swing.JInternalFrame {
    //Estamos declarando un variable de memoria dtm del tipo DefaultTableModel
    ClaseVectores VC = new ClaseVectores();
    String titulos[]= new String[5];
    DefaultTableModel dtm = new DefaultTableModel(VC.clientes,titulos);
    //Instancian un nuevo modelo del Table en la variable dtm
    //espcificiando que contendra una matriz para los datos, y un vector
    //para los identificadores de columna o titulos

    /** Creates new form frmcliente */
    public frmcliente() {
    initComponents();
    //llenamos el vector con los identificadores de columna en el
    //constructor para poder trabajarlos
    titulos[0] =»Doc. Ide»;
    titulos[1] =»Razon Social»;
    titulos[2] =»Ciudad»;
    titulos[3] =»Direccion»;
    titulos[4] =»Telefono»;
    jTable1.setModel(dtm);
    dtm.setDataVector(VC.clientes, titulos);

    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    // TODO add your handling code here:

    boolean verifica;
    verifica = jTextField1.getText().equals(«») || jTextField2.getText().equals(«») || jTextField3.getText().equals(«») || jTextField4.getText().equals(«»);
    int contador_cliente = 0;

    if (!verifica){

    VC.clientes[contador_cliente][0] = String.valueOf(jTextField1.getText());
    VC.clientes[contador_cliente][1] = String.valueOf(jTextField2.getText());
    VC.clientes[contador_cliente][2] = String.valueOf(jComboBox2.getSelectedItem());
    VC.clientes[contador_cliente][3] = String.valueOf(jTextField3.getText());
    VC.clientes[contador_cliente][4] = String.valueOf(jTextField4.getText());

    jTable1.setModel(dtm);
    dtm.setDataVector(VC.clientes, titulos);
    }
    }

    cada vez que le doy click al boton aumnta mi contador por consiguiente se guarda en una fila diferente
    Lo que deseo es cada vez que dea click se llene mi jtable.
    Lo unico que logro es que grabe pero siempre en la primera fila, espero puedan aayudarme..
    Cabe resaltar que nunca eh programado en Java con netbeans, solo con VB o PB pero java es la primera vez, gracias de antemano

    • 17 junio, 2011 a las 21:47

      Lo que pasa es que contador_cliente está declarado e inicializado dentro del mismo listener del evento del botón. Por eso su valor va a ser cero con cada clic.

      La única forma de evitar que el contador se «resetee» es declararlo como un atributo de la clase (igual que dtm) y asignarle cero ahí mismo o en el constructor. Y también habría que incrementarlo cada vez que se agregue un cliente. Eso sí tiene que ir en el listener.

      Eso debería resolver el problema.

  14. Alejandro Ignacio Bonilla Alfaro
    26 febrero, 2012 a las 22:28

    Hola necesito ayuda . para poder acceder a la tabla a trabes de un controlador, para utilizar la metodología modelo vista controlador, y como veo en tu ejemplo este esta ejecutado sobre la vista, pero no hay alguna forma de poder agregar columnas y filas desde el controlador ??

    eso si me puedes ayudar seria de gran ayuda gracias.

  15. NOE
    30 abril, 2012 a las 00:36

    Muy bueno, a mi me sirvio bastante, aunq básico pero muy util

  16. 7 May, 2012 a las 06:59

    Hola amigo eso me sirve tambien para cuando hay conexion a base de datos y necesito trabjar sobre el jtable?

  17. 7 May, 2012 a las 10:48

    Necesito conectar un jtable con netbeans a oracle y la verdad soy novato y no tengo mucha idea de esto agradezco tu ayuda

    • 15 May, 2012 a las 22:24

      Perdón por la tardanza…

      Por si no lo has resuelto, la idea es consultar la base de datos y agregar cada registro al JTable. Eso significa que para cada registro se recuperan los valores y se forma con ellos el vector que se agrega al JTable por medio del método addRow().

      La verdad desconozco si hay una forma más directa para relacionar los datos con el JTable.

  18. Ana Itzel Jiménez
    24 May, 2012 a las 15:36

    Hola, necesito tu ayuda y asesoría. Quiero hacer un software contable, pienso hacerlo con JTable, pero tengo problemas, quiero sumar dos de mis filas y mostrarlas en otra. Es posible..? Gracias!

    • 24 May, 2012 a las 20:33

      Podrías usar el método getValueAt para recuperar los valores de celdas específicas.
      Habría que recorrer las columnas con un ciclo, sumar los valores de las celdas de filas diferentes (casteándolos antes) y escribir el resultado en otra con el método setValueAt.

  19. 23 junio, 2012 a las 20:38

    Hola, como podria marcar una fila requerida en un jTable y como podria capturar la fila que clickie para poder usar ese dato….Gracias!!!

    • 24 junio, 2012 a las 10:15

      Aquí hay un ejemplo de diferentes modos de selección en un JTable. El código fuente se encuentra aquí.

      En resumen, se agregan listeners a los modelos de selección (SelectionModel) del JTable con:

      table.getSelectionModel().addListSelectionListener(new RowListener());
      table.getColumnModel().getSelectionModel().addListSelectionListener(new ColumnListener());

      Los listeners son:

      private class RowListener implements ListSelectionListener {
      public void valueChanged(ListSelectionEvent event) {
      if (event.getValueIsAdjusting()) {
      return;
      }
      // Código útil...
      }
      }

      private class ColumnListener implements ListSelectionListener {
      public void valueChanged(ListSelectionEvent event) {
      if (event.getValueIsAdjusting()) {
      return;
      }
      // Código útil...
      }
      }

      Para recuperar los índices de la celda «lead» (la última celda que obtuvo el foco) se usa table.getSelectionModel().getLeadSelectionIndex() para la fila y table.getColumnModel().getSelectionModel().getLeadSelectionIndex() para la columna.

      Y para los índices de las celdas seleccionadas se usan table.getSelectedRows() y table.getSelectedColumns() para las filas y columnas respectivamente.

  20. Ing. Juan Mancilla
    18 septiembre, 2012 a las 19:24
  21. Matías Evert
    2 marzo, 2013 a las 20:43

    Gracias amigo por solucionar mi problema, el código lo tenia bueno pero no hallaba la forma de que me mostrara los datos en la jTable. Después de 2 días por fin logré realizarlo. De verdad gratitud hacia tí :)

  22. 29 abril, 2013 a las 09:45

    Great goods from you, man. I’ve understand your stuff previous to and you’re just
    extremely excellent. I actually like what you have acquired here, really
    like what you’re saying and the way in which you say it. You make it entertaining and you still care for to keep it sensible. I can not wait to read much more from you. This is actually a tremendous web site.

  23. walter asanza
    18 septiembre, 2014 a las 20:59

    ola como hago para que el swing control me muestre el jtable

  24. marcela
    24 marzo, 2015 a las 18:10

    hola! necesito una gran ayuda! me puedes ayudar por medio del correo???

  25. Prospero
    23 noviembre, 2016 a las 08:04

    sabes como poner un boton dentro de una celda del jtable asi como este ejemplo usando el editor de netbeans. gracias de antemano

    • 25 diciembre, 2017 a las 22:20

      ya probaste con, null layout,?? esto te sirve para sobreponer las herramientas, como botones, tablas, labels. ahi podras poner tu boton sobre la celda que deseas.

  26. men
    17 enero, 2020 a las 23:12

    I do accept as true with all the ideas you’ve presented for your post.
    They’re really convincing and can definitely work.
    Still, the posts are too brief for beginners. Could you please extend them a little from next time?
    Thanks for the post.

  1. 15 octubre, 2014 a las 20:33

Replica a Temo Cancelar la respuesta