Estás en: Inicio >> Foros >> Informática >> Programación
Programación /

Problema con el CellRenderer de JTable

Participa en el tema Problema con el CellRenderer de JTable en el foro Programación.
Tengo el siguiente problema: he creado un objeto (javax.swing.JTable) miTabla, pasandole al constructor (javax.swing.table.DefaultTableModel) miModelo ...

Buscar en este tema:
 
  •  
    #1 Problema con el CellRenderer de JTable
    Tengo el siguiente problema:
    he creado un objeto (javax.swing.JTable) miTabla, pasandole al constructor (javax.swing.table.DefaultTableModel) miModelo de la siguiente forma:

    DefaultTableModel miModelo = new DefaultTableModel;
    JTable miTabla = new miTabla(miModelo);

    Independiente a esto he creado una nueva clase miRender al cual le he implementado TableCellRenderer

    public class miRender implements TableCellRenderer{
    public Component getTableCellRendererComponent(....
    //mi codigo...

    luego a mi tabla "miTabla" por medio del metodo "setDefaultRenderer", doy colores a las celdas de "miTabla"

    miTabla.setDefaultRenderer(Object.class, new miRender());

    y no tengo ningun problema como veran en la siguiente imagen:


    mi problema radica cuando desplego el combobox MES:

    y me mezcla los colores de la celda, esto ocurre cuando el numero de filas supera el tamaño de mi JTable y al tocar el scroll vertical
    Imágenes adjuntas
    Tipo de archivo: jpg render1.jpg (44.5 KB, 31 vistas)
    Tipo de archivo: jpg render2.jpg (43.0 KB, 33 vistas)
    Tipo de archivo: jpg render3.jpg (41.1 KB, 32 vistas)
    +
     
    0
    Me gusta
     
    http://www.psicofxp.com/forums/programacion.313/872799-problema-con-el-cellrenderer-de-jtable.html
    | Más
  • #2 Re: Problema con el CellRenderer de JTable

    Obviamente está mal tu clase miRender. Ahora, no entiendo si pretendés que te la arreglemos telepáticamente o qué...
    Me gusta este mensaje
  • #3 Re: Problema con el CellRenderer de JTable

    Este es mi clase miRender que implementa TableCellRenderer.
    Su funcionamiento es basicamente cambiar el color de toda la fila cuando el valor de la colmna 1 es
    diferente a la anterior.

    package Render;
    import java.awt.Color;
    import java.awt.Component;
    import javax.swing.JLabel;
    import javax.swing.JTable;
    import javax.swing.table.TableCellRenderer;

    public class miRender implements TableCellRenderer{
    Color colorAnterior;
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
    JLabel etiqueta = new JLabel();
    if(!isSelected){
    if(row == 0){
    etiqueta.setBackground(codecColor(0));
    colorAnterior = etiqueta.getBackground();
    }else{
    if(column == 0){
    if(table.getValueAt(row, 0).equals(table.getValueAt(row-1, 0))){
    etiqueta.setBackground(colorAnterior);
    }else{
    etiqueta.setBackground(cambiarColor(colorAnterior));
    colorAnterior = etiqueta.getBackground();
    }
    }else{
    etiqueta.setBackground(colorAnterior);
    }
    }
    if(column == 0){
    etiqueta.setForeground(Color(153,0,0));
    etiqueta.setFont(new javax.swing.plaf.FontUIResource("Tahoma", 1, 12));
    }
    }
    if (value instanceof Object){
    etiqueta.setOpaque(true);
    etiqueta.setText(value.toString());
    }
    return etiqueta;
    }
    private Color cambiarColor(Color colorActual){
    if(colorActual.equals(codecColor(0)))
    return codecColor(1);
    else
    return codecColor(0);
    }
    private Color codecColor(int codec){
    if(codec%2 == 0){
    return Color(90,225,70);
    }else{
    return Color(220,220,120);
    }
    }
    private Color Color(int i, int i0, int i1) {
    return new Color(i, i0, i1);
    }
    }
    -----Agregado el 11/12/2008 a las 09 : 50 : 25-----
    Agradeceria mucho si pueden mirar la clase y decirme si esta mal para poder corregirlo.
    Editado por marcewar - 11.12.2008 08:50 hs. | Motivo: Mensajes unidos automáticamente
    Me gusta este mensaje
  • #4 Re: Problema con el CellRenderer de JTable

    El problema está en que tu código supone que las celdas se van a pintar siempre desde la primera hasta la última fila y, dentro de cada fila, desde la primera hasta la última columna. Calcula qué color usar sólo en la columna 0 y lo guarda en una variable. Entonces sucede lo siguiente:
    1. Va a devolver el componente de la última fila "10". Calcula que el color es verde y lo guarda en colorAnterior.
    2. Usa colorAnterior para el resto de las etiquetas de la fila "10"
    3. El usuario despliega el combobox y lo vuelve a pegar
    4. Hay que redibujar algunas celdas de las filas "01", "02" ... "07", pero del medio de las filas. No se pide el componente para la columna 0, así que colorAnterior sigue siendo verde, y las celdas se pintan de color verde.

    Lo que hay que hacer es calcular el color de cada celda por separado, sin basarse en el contenido de ninguna otra celda, ya que no está garantizado que ninguna celda vaya a procesarse antes de otra (o tal vez sí, pero es mejor hacer como si no).

    Por ejemplo, tu clase podría funcionar así (ojo, sin probar):
    Código:
    class miRender implements TableCellRenderer, TableModelListener {
      Color ROJO = new Color(153,0,0);
      Color AMARILLO = new Color(220,220,120);
      Color VERDE = new Color(90,225,70);
      Map colores = new HashMap(31);
    
      void updateColores(JTable t)
      {
        Object oldval = null;
        Color c = VERDE;
        for (int i=0; i<t.getRowCount(); i++) {
          if (oldval != null && !oldval.equals(t.getValueAt(i, 0))) {
            if (c == VERDE) c = AMARILLO; else c = VERDE;
          }
          oldval = t.getValueAt(i, 0);
          colores.put(oldval, c);
        }
      }
    
      public void tableChanged (TableModelEvent e) { colores.clear(); }
    
      public Component getTableCellRendererComponent (JTable table, Object value,
          boolean isSelected, boolean hasFocus, int row, int column)
      {
        JLabel etiqueta = new JLabel();
        if (value == null) return etiqueta;
        etiqueta.Text = value.toString();
        if (column == 0) {
          etiqueta.setForeground(ROJO);
          etiqueta.setFont(new javax.swing.plaf.FontUIResource("Tahoma", 1, 12));
        }
        if (colores.isEmpty()) updateColores(table);
        etiqueta.setBackground(colores.get(table.getValueAt(row, 0)));
        return etiqueta;
      }
    }
    
    Seguramente hay que ajustar algunos detalles. Obvié la parte de "if (!isSelected)" porque en tu código es imposible distinguir dónde empiezan y terminan los ifs.

    El método (en teoría) precalcula el color de cada fila cuando le piden el primer componente, sin importar en qué posición esté. El resto de las veces usa los valores precalculados, que están en el HashMap colores indexados por el valor de la primera columna. Cada vez que se modifica la tabla, resetea el HashMap. Hay que agregar esta clase a los eventos del modelo de la tabla ("miModelo.addTableModelListener(miRender)").

    Saludos.
    Editado por pangus - 11.12.2008 11:17 hs.
    Me gusta este mensaje
  • #5 Re: Problema con el CellRenderer de JTable

    Muchas gracias pangus por tu tiempo y por facilitarme un solucion posible.
    He probado tu codigo y aunque no me funciono tal cual, me ha servido para entender el modo en que este metodo "getTableCellRendererComponent" trabaja sobre las celdas del JTable
    Adjunto el codigo con el cual he solucionado mi problema:
    http://www.psicofxp.com/forums/attac...1&d=1229026990
    Archivos adjuntos
    Tipo de archivo: pdf miRender_solucion.pdf (35.5 KB, 30 vistas)
    Me gusta este mensaje
Estás en: Inicio >> Foros >> Informática >> Programación


Estadísticas del tema
  • 4 RESPUESTAS
  • 1312 VISTAS
  • 2 USUARIOS RESPONDIERON
 
Ir arriba
Contacto | Acerca de | Ayuda | Términos Legales | privacidad | Pautas de convivencia | Mapa de los foros | TrabajÁ con nosotros
©2008 Psicofxp.com S.A. - Todos los derechos reservados
Certifica IAB