Saltar al contenido

Procesador de celda de JTable

Ya no busques más en otros sitios ya que estás al sitio justo, tenemos la respuesta que quieres pero sin problemas.

Solución:

¿Se ha utilizado alguna vez su renderizador? Lo convierte en el renderizador predeterminado para las celdas que contienen String, pero ha sobrecargado el modelo getColumnClass método para que sepa que algunas de las celdas contienen cadenas?

Entonces, primero usaría declaraciones println para ver si se está llamando al renderizador y, de lo contrario, anularía el método de mi modelo como se indicó anteriormente.

Editar 1

Además, sus resultados de if seguramente serán extraños. En la parte if, cambia el primer plano y en el else cambia el fondo, no tiene sentido. Probablemente debería hacer cambios complementarios en el estado en los bloques if versus else, no cambios ortogonales.

Editar 2

Por ejemplo:

import java.awt.*;
import java.util.Random;

import javax.swing.*;
import javax.swing.table.*;

public class Board extends JPanel 

   private static final long serialVersionUID = 1L;

   int boardHeight = 20;
   int boardWidth = 10;

   JTable table;
   Random random = new Random();

   public Board() 
      setLayout(new BorderLayout()); // !!
      DefaultTableModel model = new DefaultTableModel(boardHeight, boardWidth) 
         @Override
         public Class getColumnClass(int columnIndex) 
            return String.class;
         
      ;
      // !! table = new JTable(this.boardHeight, this.boardWidth);
      table = new JTable(model);
      for (int row = 0; row < model.getRowCount(); row++) 
         for (int col = 0; col < model.getColumnCount(); col++) 
            String s = random.nextBoolean() ? "red" : "yellow";
            model.setValueAt(s, row, col);
         
      
      table.setDefaultRenderer(String.class, new BoardTableCellRenderer());

      table.setFocusable(false);
      table.setShowGrid(false);
      table.setRowMargin(0);
      table.setIntercellSpacing(new Dimension(0, 0));
      table.setRowSelectionAllowed(false);
      table.setVisible(true);
      this.add(table);
      this.setPreferredSize(new Dimension(table.getPreferredSize().width,
               (table.getPreferredSize().height + 85)));
   

   private static void createAndShowUI() 
      JFrame frame = new JFrame("Board");
      frame.getContentPane().add(new Board());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   

   public static void main(String[] args) 
      java.awt.EventQueue.invokeLater(new Runnable() 
         public void run() 
            createAndShowUI();
         
      );
   


class BoardTableCellRenderer extends DefaultTableCellRenderer 

   private static final long serialVersionUID = 1L;

   public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int col) 

      Component c = super.getTableCellRendererComponent(table, value,
               isSelected, hasFocus, row, col);
      Object valueAt = table.getModel().getValueAt(row, col);
      String s = "";
      if (valueAt != null) 
         s = valueAt.toString();
      

      if (s.equalsIgnoreCase("yellow")) 
         c.setForeground(Color.YELLOW);
         c.setBackground(Color.gray);
       else 
         c.setForeground(Color.black);
         c.setBackground(Color.WHITE);
      

      return c;
   

Agrega esta línea:

c.setOpaque(true);

El componente devuelto por getTableCellRendererComponent debe ser opaco para ver cambios en el color de fondo y primer plano. El problema aquí también es otro: está extendiendo DefaultTableCellRenderer (que es un JComponent) pero está devolviendo un Component que no tiene el método setOpaque. Refactorizaría su código de esta manera:

public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int col) 

    String s = table.getModel().getValueAt(row, col).toString();
    this.setOpaque(true);
    if (s.equalsIgnoreCase("yellow")) 
        this.setForeground(Color.YELLOW);
    
    else 
        this.setBackground(Color.WHITE);
    

    return this;

Aquí hay una solución simple, use TableCellRenderer como una clase interna.

    myTable.setDefaultRenderer(Object.class, new TableCellRenderer()
    
        JLabel comp = new JLabel();
        String val;

        @Override
        public Component getTableCellRendererComponent(
                             JTable table, 
                             Object value, 
                             boolean isSelected, 
                             boolean hasFocus, 
                             int row, 
                             int column)
        
            comp.setOpaque(true);
            comp.setForeground(Color.BLACK); // text color

            if (value != null)
            
                val = value.toString();
                comp.setText(val);

                if (val.equalsIgnoreCase("red"))
                
                    comp.setBackground(Color.RED);
                
                else if (val.equalsIgnoreCase("yellow"))
                
                    comp.setBackground(Color.YELLOW);
                
                else if (val.equalsIgnoreCase("green"))
                
                    comp.setBackground(Color.GREEN);
                
                else
                
                    comp.setBackground(Color.WHITE);
                
            
            return comp;
        
    );

Sección de Reseñas y Valoraciones

Eres capaz de ayudar nuestro trabajo añadiendo un comentario o dejando una puntuación te damos las gracias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *