Foros del Web » Programación para mayores de 30 ;) » Java »

Error Al inicializar un JTable e usando una clase AbstractTableModel

Estas en el tema de Error Al inicializar un JTable e usando una clase AbstractTableModel en el foro de Java en Foros del Web. Hola, no entiendo porque sucede este error.. Mi interfaz grafica consiste en que debo mostrar una lista de productos, con su respectivo precio y la ...
  #1 (permalink)  
Antiguo 03/10/2013, 23:47
 
Fecha de Ingreso: octubre-2013
Ubicación: En mi casita
Mensajes: 7
Antigüedad: 10 años, 6 meses
Puntos: 0
Pregunta Error Al inicializar un JTable e usando una clase AbstractTableModel

Hola, no entiendo porque sucede este error.. Mi interfaz grafica consiste en que debo mostrar una lista de productos, con su respectivo precio y la cantidad disponible. Ademas de datos en otra tabla que aún no la he implementado porque se me ha presentado el siguiente problemita:

[URL="http://www.subirimagenes.net/i/131004064415224533.jpg"]http://www.subirimagenes.net/i/131004064415224533.jpg[/URL]

Mis codigos son los siguientes:

ESTA ES LA CLASE QUE CONTIENE EL FORMULARIO Y TODOS LOS COMPONENTES
Código:
package consultaproductos;

import javax.swing.JOptionPane;

public class ConsultarProductos extends javax.swing.JFrame 
{
    
    TableModelProductosDisponibles productosDisponiblesModel=new TableModelProductosDisponibles();
    Factura facturaModel=new Factura();
    
    public ConsultarProductos() 
    {
        initComponents();
        inicializarColumnasTablaProductosDisponibles();
    }
    
    private void inicializarColumnasTablaProductosDisponibles()
    {
       javax.swing.table.TableColumnModel tCModel=new javax.swing.table.DefaultTableColumnModel();
       for(int i=0;i<3;i++)
       {
           javax.swing.table.TableColumn columna=new javax.swing.table.TableColumn();
           switch(i)
           {
               case 0: columna.setHeaderValue("Producto"); break;
               case 1: columna.setHeaderValue("Precio"); break;
               case 2: columna.setHeaderValue("Cantidad"); 
           }
           tCModel.addColumn(columna);
       }
       tablaDisponibles.setColumnModel(tCModel);
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        tablaDisponibles = new javax.swing.JTable();
        jLabel1 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        tablaCompras = new javax.swing.JTable();
        jLabel2 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        tablaDisponibles.setModel(productosDisponiblesModel);
        jScrollPane1.setViewportView(tablaDisponibles);

        jLabel1.setText("Productos Disponibles:");

        tablaCompras.setModel(facturaModel);
        jScrollPane2.setViewportView(tablaCompras);

        jLabel2.setText("Productos a Comprar:");

        jButton1.setText("Agregar bolsa de compras");

        jButton2.setText("Devolver producto");

        jButton3.setText("Realizar Compra");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 267, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1)
                    .addComponent(jButton1))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                        .addGap(18, 18, 18))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jButton2)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 158, Short.MAX_VALUE)
                                .addComponent(jButton3))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel2)
                                .addGap(0, 0, Short.MAX_VALUE)))
                        .addContainerGap())))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(20, 20, 20)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 240, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jButton2)
                            .addComponent(jButton1))
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 16, Short.MAX_VALUE)
                        .addComponent(jButton3)
                        .addGap(22, 22, 22))))
        );

        pack();
    }// </editor-fold>                        


    
    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTable tablaCompras;
    private javax.swing.JTable tablaDisponibles;
    // End of variables declaration                   
}

ESTE ES EL CODIGO DE LA CLASE PRODUCTO
Código:
package consultaproductos;

public class Producto 
{
    private String nombre;
    private double precio;
    private int cantidad;

    public void setNombre(String nombre){
       this.nombre=nombre;
    }
    
    public String getNombre(){
        return nombre;
    }
    
    public void setPrecio(double precio){
       this.precio=precio;
    }
    
    public double getPrecio(){
       return precio;
    }
    
    public void setCantidad(int cantidad){
       this.cantidad=cantidad;
    }
    
    public int getCantidad(){
        return cantidad;
    }
}
ESTE ES EL CODIGO DE MI MODELCLASS PARA MI TABLA
Código:
package consultaproductos;
import javax.swing.table.AbstractTableModel;
import java.util.List;
import java.util.ArrayList;

public class TableModelProductosDisponibles extends AbstractTableModel
{
    ArrayList<Producto> listaProductosDisponibles=new ArrayList<Producto>(); //Lo que está dentro de <> se llama genericidad. La clase ArrayList permite crear una lista redimensionable

    
    @Override
    public int getRowCount(){
        return listaProductosDisponibles.size();
    }
    
    @Override
    public int getColumnCount(){
       return 3;
    }
    
    @Override
    public Object getValueAt(int rowIndex, int columnIndex){
       Object returning=new Object();
       switch(columnIndex){
           case 0: returning=listaProductosDisponibles.get(rowIndex).getNombre();
               break;
           case 1: listaProductosDisponibles.get(rowIndex).getPrecio();
               break;
           case 3: listaProductosDisponibles.get(rowIndex).getCantidad();
       }
       return returning;
    }

    
}

ESTE ES EL PRINCIPAL
Código:
package consultaproductos;
import java.util.Random;


public class Prueba 
{

    public static void main(String[] args)
    {
        String[] nombreProductos={"Lapicero","Cuaderno","Aceite","Pintura","Lentes","Pantalon","Camiseta","Reloj","Calculadora","Computadora","Vaso","Minas","Bolson","Celular","Manzana"};
        
        ConsultarProductos ventanaDeConsulta=new ConsultarProductos();
        Random aleatorio=new Random();
        
        for(int i=0;i<nombreProductos.length;i++)
        {
            Producto prod=new Producto();
            
            prod.setNombre(nombreProductos[i]);
            prod.setPrecio(aleatorio.nextDouble()*50);
            prod.setCantidad(aleatorio.nextInt(50));
            
            System.out.println(prod.getCantidad());
            System.out.println(prod.getPrecio());
            System.out.println(prod.getNombre());
            
            ventanaDeConsulta.productosDisponiblesModel.listaProductosDisponibles.add(prod);
        }
        ventanaDeConsulta.setVisible(true);
    }
  #2 (permalink)  
Antiguo 04/10/2013, 09:23
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

Hola:

En case 1 y 3 no rellenas el returning que estás devolviendo. ¿Qué paso con el case 2?

Código Java:
Ver original
  1. switch(columnIndex){
  2.            case 0: returning=listaProductosDisponibles.get(rowIndex).getNombre();
  3.                break;
  4.            case 1: listaProductosDisponibles.get(rowIndex).getPrecio();
  5.                break;
  6.            case 3: listaProductosDisponibles.get(rowIndex).getCantidad();
  7.        }
  8.        return returning;


Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #3 (permalink)  
Antiguo 04/10/2013, 13:24
 
Fecha de Ingreso: octubre-2013
Ubicación: En mi casita
Mensajes: 7
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

Ya corregí el switch, pero el problema siempre continúa. Esque lo que quiero es que cada atributo de la clase Producto se imprima en una fila de la tabla en las columnas correspondientes. Para ello, en la clase TableModelProductosDisponibles cree un ArrayList de objetos de tipo Producto para que automáticamente se impriman una fila y en las columnas correspondientes los tres atributos de los objetos Producto... Pero no se que hay habré hecho mal :(
  #4 (permalink)  
Antiguo 04/10/2013, 14:23
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

Como no te expliques mejor....

Después de los cambios que has corregido ¿Qué es lo que sale ahora y qué es lo que quieres que salga?

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #5 (permalink)  
Antiguo 04/10/2013, 21:55
 
Fecha de Ingreso: octubre-2013
Ubicación: En mi casita
Mensajes: 7
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

Lo que sucede es que tengo problemas al incializar una tabla en mi interfaz grafica.

Lo que deseo ver en esa tabla es:

PRODUCTO ------PRECIO ------- CANTIDAD
Detergente-------1.65-------------54
Aceite--------------3.54-------------35
Cuaderno---------1.00-------------45


Pero lo que veo en la tabla es lo siguiente:

PRODUCTO --------PRECIO -------------- CANTIDAD
Detergente--------Detergente-----------Detergente
Aceite---------------Aceite------------------Aceite
Cuaderno----------Cuaderno-------------Cuaderno


Tengo una clase Producto con los atributos : nombre, precio, cantidad. Esos mismos atributos son los que se tienen que ver en la tabla, cada atributo en su columna correspondiente. En la clase principal (que contiene el main) creo un conjunto de productos ya sus los atributos inicializados y se los paso a la clase TableModelProductosDisponibles. Ésta ultima clase contiene un ArrayList con todos los productos que el main le ha enviado. Ademas ésta misma clase TableModelProductosDisponibles es la clase modelo de la tabla, osea extiende a AbstractTableModel e implementa algunos de sus metodos.

Entonces yo creo que el error ha de estar precisamente en TableModelProductosDisponibles, o no lo se :/. No se si me entienden.

Ademas recuerdo que la primera vez que ejecuté si pude ver la tabla con sus datos correctos, luego agrege mas codigo-ya no recuerdo que codigo-y cuando volví a ejecutar mi tabla ya estaba con los datos erroneos :(.
  #6 (permalink)  
Antiguo 05/10/2013, 00:07
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

Es el mismo problema del primer post, ya te dije como solucionarlo. ¿Cómo has dejado ese trozo de código?

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #7 (permalink)  
Antiguo 05/10/2013, 21:41
 
Fecha de Ingreso: octubre-2013
Ubicación: En mi casita
Mensajes: 7
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

El codigo lo modifique asi:

Código:
    switch(columnIndex){
               case 0: returning=listaProductosDisponibles.get(rowIndex).getNombre();
                   break;
               case 1: listaProductosDisponibles.get(rowIndex).getPrecio();
                   break;
               case 2: listaProductosDisponibles.get(rowIndex).getCantidad();
           }
           return returning;

Sin embargo el problema aún continúa.
  #8 (permalink)  
Antiguo 06/10/2013, 01:16
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

Te puse esto antes

"En case 1 y 3 no rellenas el returning que estás devolviendo. ¿Qué paso con el case 2?"

Has hecho caso a lo de "¿Qué paso con el case 2?" , pero has ignorado totalmente la primera parte "En case 1 y 3 no rellenas el returning que estás devolviendo", así que efectivamente, seguirá sin funcionar.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #9 (permalink)  
Antiguo 06/10/2013, 11:39
 
Fecha de Ingreso: octubre-2013
Ubicación: En mi casita
Mensajes: 7
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

Diosss, claro es cierto ja ja, esque no habia compredido eso de rellenar, hoy si mi trozo de codigo ha quedado asi:

Código:
switch(columnIndex){
           case 0: returning=listaProductosDisponibles.get(rowIndex).getNombre();
               break;
           case 1: returning=listaProductosDisponibles.get(rowIndex).getPrecio();
               break;
           case 2: returning=listaProductosDisponibles.get(rowIndex).getCantidad();
       }

Pero ,sigue saliendo mal, y me doy cuenta de que es porque la variable returning siempre esta tomando el mismo valor tres veces por cada objeto Producto.
Es decir por cada objeto producto la variable returning toma unicamente el atributo "name" de dicho producto. y todo ésto es debido a que el parametro columnIndex del metodo en el cual está incluido éste trozo de codigo siempre llega con un valor de 0, cuando lo correcto sería que primero llegase con un valor de 0, luego con un valor de 1, luego con un valor de 2, y luego nuevamente con un valor de 0 para comenzar a tomar los atributos de un nuevo objeto producto.

No se si estoy sobre escribiendo mal éste metodo, que es el metodo getValueAt(), heredado de la clase AbstractTableModel. Aqui les dejo como lo tengo actualmente éste metodo:

Código:
@Override
    public Object getValueAt(int rowIndex, int columnIndex)
    {
       Object returning=new Object();
       switch(columnIndex)
       {
           case 0: returning=listaProductosDisponibles.get(rowIndex).getNombre();
               break;
           case 1: returning=new Double(listaProductosDisponibles.get(rowIndex).getPrecio());
               break;
           case 2: returning=new Integer(listaProductosDisponibles.get(rowIndex).getCantidad());
       }
       return returning;
    }
solucioné parcialmente éste problema agregando codigo dentro de éste metodo para que el valor de columnIndex tomara el valor de 0 en la primera llamada al metodo, 1 en la segunda llamada, 2 en la tercera, y luego nuevamente 0. Al principio todo se ve muy bonito, la tabla si toma los valores correctos, pero una vez me ubico en una celda dada, los datos en esa fila comienzan a desordenarse, y asi pasa con cualquier otra celda.

Asique pienso que el problema esta en donde se realiza la invocacion de éste metodo (getValueAt()), ya que es ahi donde no se le está pasando el parametro columnIndex correcto. Pero no se ni quien es el encargado de invocar a éste metodo, y ni se si se incluye en alguna parte del codigo que genera la paleta de componentes de netbeans.
  #10 (permalink)  
Antiguo 06/10/2013, 12:07
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

A ese método le llama el JTable y lo invoca de forma correcta, cuando debe y con los valores de los parámetros que debe, salvo que desconfíes de la implementación de java del JTable.

¿Puedes detallar qué es exactamente eso de "me ubico en una celda" y cómo se desordenan exactamente los datos de esa fila?. Es decir, "me ubico" quiere decir ¿que haces click en la celda? ¿Que haces doble click para editarla? y lo de se desordenan .. ¿sólo la celda que has seleccionado/editado? ¿Qué valor coje?

No estoy seguro, pero este trozo de código también puede ser problemático (o quizás esté bien, no lo sé, pero lo vero raro, estás metiendo tres veces el TableColumnModel, ya que lo haces dentro del bucle).

Código Java:
Ver original
  1. private void inicializarColumnasTablaProductosDisponibles()
  2.     {
  3.        javax.swing.table.TableColumnModel tCModel=new javax.swing.table.DefaultTableColumnModel();
  4.        for(int i=0;i<3;i++)
  5.        {
  6.            javax.swing.table.TableColumn columna=new javax.swing.table.TableColumn();
  7.            switch(i)
  8.            {
  9.                case 0: columna.setHeaderValue("Producto"); break;
  10.                case 1: columna.setHeaderValue("Precio"); break;
  11.                case 2: columna.setHeaderValue("Cantidad");
  12.            }
  13.            tCModel.addColumn(columna);
  14.        }
  15.        tablaDisponibles.setColumnModel(tCModel);
  16.     }

Más que nada, porque es totalemente innecesario y hay forma más fácil de hacerlo. En tu AbstractTableModel, sobreescribe el método getColumnName() para que devuelva el nombre de la columna (ya estás sobreescribiendo el getColumnCount()). Con eso basta para reemplazar todo ese código que quizás no esté bien.

Se bueno.
__________________
Apuntes Java
Wiki de Programación

Última edición por chuidiang; 06/10/2013 a las 12:15
  #11 (permalink)  
Antiguo 06/10/2013, 15:24
 
Fecha de Ingreso: octubre-2013
Ubicación: En mi casita
Mensajes: 7
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

chuidiang Tienes toda la razon, ese trozo de codigo era el que estaba gerando el error ja ja , muchas gracias por tu ayuda, hoy aprendi algo nuevo con ese metodo que me sugeriste.

Lo unico que ahora tengo un nuevo problema .

Ejecuto el programa la primera vez y todo anda muy bien, la tabla tiene los datos que debería tener y los datos tambien están estables, luego cierro la aplicacion (la que he programado), cuando la abro nuevamente la tabla aparece vacía, solo aparecen los encabezados de la tabla, pero sin ningun dato en ella.

Tengo que reiniciar NetBeans para poder ver todos los datos en mi tabla nuevamente al ejecutarla por primera vez. Es decir a partir de la segunda ejecucion la tabla aparece vacía, y no se porque será. quiza ni siquiera esté relacionada con el codigo de la aplicacion, pero creo que no es algo que debería suceder.
  #12 (permalink)  
Antiguo 06/10/2013, 15:53
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

¿Qué quiere decir "cierro la aplicación"? ¿Matas el programa y cuando lo rearrancas no salen los datos? ¿O sólo minimizas o cierras la ventana sin terminar la ejecución?

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #13 (permalink)  
Antiguo 06/10/2013, 16:04
 
Fecha de Ingreso: octubre-2013
Ubicación: En mi casita
Mensajes: 7
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Error Al inicializar un JTable e usando una clase AbstractTableModel

Si cierro completamente la aplicacion con el botoncito rojo de la ventana, y luego lo vuelvo a ejecutar y los datos de la tabla ya no se inicializan.

Esto ocurre cuando la cierro mediante el boton de la propia ventana, y tambien cuando detengo la ejecucion del programa por medio del IDE (NetBeans) que ahi me da una opcion para deternerlo.

Tambien para iniciar el programa lo hago mediante el IDE.

Pero si mato el programa no lo estoy ocultando ni minimizando. lo mato y luego lo rearranco

Última edición por ssssaaamm; 06/10/2013 a las 16:12

Etiquetas: clase, inicializar, jtable, string, usando
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 04:47.