es posible cargar un jtable con mas de 200 mil regitros????

es posible cargar en un jtable cargar esa cantidad de registros si que se me ponga extremadamente lento

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

no se si mi problema radica es querer ...

no se si mi problema radica es querer usar una tabla generica para todo, estoy aprendiendo algo de introspeccion en java y no se mi proble radique en eso

public class TableModelGeneric<T> extends AbstractTableModel{
   
      private final Class beanClass;
      private List<T> data = new ArrayList<T>();
     
      private List<Field> columns2 = new ArrayList<Field>();
      //private List<Method> metodos = new ArrayList<Method>();
      List<String> listNames = new ArrayList<String>();

    public List<Field> getColumns2() {
        return columns2;
    }

    public List<String> getListNames() {
        return listNames;
    }
   
   
     
       public TableModelGeneric(Class beanClass)
       {
        if (beanClass == null) {
            throw new IllegalArgumentException("Bean class required, cannot be null");
        }
        this.beanClass = beanClass;
       
        populateColumns2();
    }

   
       public List<T> getData()
       {
        return data;
       }

       public void setData(List<T> data)
       {
            this.data = data;
            fireTableDataChanged();
       }

       @Override
       public int getRowCount()
       {
          return data.size();
       }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
   
        return columns2.get(columnIndex).getClass();
    }

    @Override
    public String getColumnName(int column) {
   
        if(columns2.get(column).isAnnotationPresent(Columna.class))
        return columns2.get(column).getAnnotation(Columna.class).name();
        else
            return
                    columns2.get(column).getName();
    }

    @Override
    public int getColumnCount() {
        return columns2.size();
       
       
    }

      @Override
    public Object getValueAt(int rowIndex, int columnIndex)
    {
        Object value= null;
        try{
         Field  f = columns2.get(columnIndex);
         Method m = beanClass.getMethod("get"+f.getName().substring(0,1).toUpperCase()+f.getName().substring(1,f.getName().length()));
         T bean =   data.get(rowIndex);
         value  =   m.invoke(bean);
        }
        catch(Exception e)
        {}
        return value;
    }
    private void populateColumns2(){
       
          List<Field> listaCampos=new ArrayList<Field>();
         // List<Method> listaMetodos=new ArrayList<Method>();
          for(Field f: beanClass.getDeclaredFields()){
           if(f.isAnnotationPresent(Columna.class))
            {
              listaCampos.add(f);
              listNames.add(f.getAnnotation(Columna.class).name());
             
            }
         }
       
          if(listaCampos.isEmpty()){
              columns2.addAll(Arrays.asList(beanClass.getDeclaredFields()));
              for (Field f : beanClass.getDeclaredFields()) {
                   listNames.add(f.getName());
              }
             
          }
          else
          {
            columns2.addAll(listaCampos);
          }
    }
 
}

Independientemente de la

Independientemente de la parte tecnológica, es una mala experiencia para un ser humano tener que navegar entre tantos registros.

Pasando a la parte del desempeño, llamar beanClass.getMethod() por cada invocación de getValueAt es completamente innecesario, solo necesitas saber una vez por columna que método te debe de resolver esa columna.

Deberia ser algo como:

// en alguna parte donde se inicializa:
private Methods[] methodForColumns  = new Method[this.getColumnCount()];
for ( int i = 0 ; i < this.methodForColumns.lenght ; i++ ) {
    methodForColumns[i] = beanClass.getMethod(....)
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)    {
     /// y luego solo usarlo
     ....
    Method m = methodsForColumns[columnIndex];
}

Como estas llamas N x M veces a getMethod, si tienes 10 columnas por 200k estas llamando al metodo 2 millones de veces, cuando solo lo necesitas invocar 10 veces.

En cuanto al estilo, en Java la llave que abre va en la misma línea, no en la linea siguiente:

//Si
public void method() {
}
//No
public void method()
{
}

despues de hacer cambios sigue lenta

despues de aplicar tus sugerencias sigue lenta se demora 20 seg en cagara 37 mil registros asi es como cargo la tabla

 private void refrescarTable(){          
           if(this.listaDatosForTable.size()>0){  
             
                    TableModelGeneric tm=new  TableModelGeneric<T>(listaDatosForTable.get(0).getClass());
                    tm.setData(listaDatosForTable);
                    sorter = new TableRowSorter (tm);
                    this.internal.getTblTablaRegistros().setModel( tm);
                    this.internal.getTblTablaRegistros().setRowSorter (sorter);
                    listaFiltro=tm.getListNames();
                    this.internal.getJComboFiltro().setModel(new DefaultComboBoxModel(listaFiltro.toArray()));
                     refreshTipoFiltros();
                     FilterText();
                    this.internal.getTblTablaRegistros().setDefaultRenderer(Object.class, new TableRendererGeneric());
                    this.internal.getTblTablaRegistros().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
                    this.internal.getTblTablaRegistros().setShowGrid(false);
                    this.internal.getTblTablaRegistros().setIntercellSpacing(new Dimension(1, 1));
                    this.internal.getTblTablaRegistros().setShowVerticalLines(true);
                    this.internal.getTxtTotalfilas().setText(""+sorter.getViewRowCount());
                    if(sorter.getViewRowCount()>0){  
                        UtilFrame.autoRizeColumn(this.internal.getTblTablaRegistros(), tm.getColumnCount(), 1);
                        firtRow();
                        //onEditar();
                        internal.enableControl();}
                    }
              else{
                    limpiartable();
                    internal.getBtnExcel().setEnabled(false);
                    UtilFrame.setMensajeInformation("No se econtraron registros para la fecha seleccionada.", "INFORMACION");
           }}

no se si aca tenga algun elemento mal diseñado o algo que me este generando la lentitud.

Imagen de rodrigo salado anaya

if else

Solo completando las observaciones de @OscarRyz te aconsejo mucho que siempre uses llaves para encerrar código como en el caso de tu primer snippet:

if(columns2.get(column).isAnnotationPresent(Columna.class))
        return columns2.get(column).getAnnotation(Columna.class).name();
        else
            return

En lugar de eso escribe algo como :

if(columns2.get(column).isAnnotationPresent(Columna.class)) {
        return columns2.get(column).getAnnotation(Columna.class).name();
}  else {
        return columns2.get(column).getName();
}

Con el tiempo te acostumbraras tanto que tus ojos sangraran cuando veas un if/else sin llaves.

ok

mirando el mayor tiempo se gasta cargador el arraylist con los 27 milregistros, sera que me toca mirar una alternativa de estructura o algo asi .

Seguramente la mayor parte de

Seguramente la mayor parte de esos 20 segundos se pase en traer datos de la base de datos por la red. La red siempre es la parte más lenta.

No es un cambio de estructura sino de estrategia lo que necesitas. Por ejemplo, en vez de traer 27k registros por la red que el usuario no va a poder mirar y dejarlo esperando todo ese tiempo, puedes traer 1,000 registros ( o 500 ) y traer la información restante en un hilo en segundo plano.

Para saber como diseñar interfaces de usuario fíjate en ejemplos que a tí te parezcan buenos, por ejemplo, Gmail no te trae tus 20 mil correos aunque los tenga porque tu no sabrías que hacer con ellos, y obviamente buscar esa información y serializarla por la red tiene un costo en el desempeño.

Puede haber muchos mejoras como esta y no es posible simplemente adivinarlas y darte sugerencias en el foro pero creo que vas en buen camino respecto a medir. Sigue así, fíjate donde se esta gastando la mayoría de tiempo y arregla esa parte. Haz comparaciones, si crees que un arraylist no resuelve lo que necesitas utiliza otra estructura, pero aisla el problema, es decir, no cambies todo tu programa para intentar la alternativa, crea un programa chiquito que represente el mismo problema , mide, haz el cambio y mide de nuevo.

todo ok

ya tengo ajustada la table generic pero tengo ahora un problema, cuando antes armaba un table para un tipo de dato especifico
y por lo general hacia esto ya sea cuando pulso click a una fila de la tabla o me desplazo con el teclado.

 this.rowIndex =this.internal.getTblTablaRegistros().getSelectedRow();
     
         if(rowIndex == -1)
         {    UtilFrame.setMensajeInformation("Seleccione  un Producto ", "INFORMACION");
              return;
         }
       
         
         int modelRow =  this.internal.getTblTablaRegistros().convertRowIndexToModel(rowIndex);
         this.filaSeleccionada= new MensajeSGVTableModels(listaDatosForTable).get(modelRow);
         
    }
   

asi seleccionaba el objecto es este caso producto, pero ahora que tengo un JTable generico no se como hacer para seleccionarlo de la misma manera.