jean-marc caspar
jean-marc caspar

Reputation: 35

Java - Jtable Color

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import java.awt.*;

public class Fenetre extends JFrame implements TableCellRenderer {
    private static TableCellRenderer tcr;

    public Fenetre(TableCellRenderer tcr){
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("Liste des PC de la DTARS");
        this.setSize(500, 250);

        Object[][] data = {
                {"nomPc", "PC Fixe", "xxxx","OK","24"},
                {"nomPc", "PC Fixe", "xxxx","OK","24"},
                {"nomPc", "PC Fixe", "xxxx","A REMPLACER","24"},
                {"nomPc", "PC Fixe", "xxxx","A REMPLACER","24"},
                {"nomPc", "PC Portable", "xxxx","OK","NA"},
                {"nomPc", "PC Portable", "xxxx","OK","NA"},
                {"nomPc", "PC Fixe", "xxxx","OK","24"},
                {"nomPc", "PC Fixe", "xxxx","OK","24"},
                {"nomPc", "PC Fixe", "xxxx","OK","24"},
                {"nomPc", "PC Fixe", "xxxx","OK","24"},
                {"nomPc", "PC Fixe", "xxxx","OK","24"},
                {"nomPc", "PC Fixe", "xxxx","OK","24"},

        };

         String  title[] = {"Nom Machine", "Type", "Utilisateur","Etat","Ecran"};
        JTable tableau = new JTable(data, title);
        //tableau.setBackground(Color.cyan);
        DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer();
        rightRenderer.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
        tableau.getColumn("Type").setCellRenderer( rightRenderer );
        tableau.getColumn("Utilisateur").setCellRenderer( rightRenderer );
        tableau.getColumn("Etat").setCellRenderer( rightRenderer );
        tableau.getColumn("Ecran").setCellRenderer( rightRenderer );
        tableau.setAutoCreateRowSorter(true);
        this.getContentPane().add(new JScrollPane(tableau));

    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component comp = this.tcr.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        if ((row & 1) == 0) { // Ligne paire
            comp.setBackground(Color.RED);
        } else { // Ligne impaire
            comp.setBackground(Color.BLUE);
        }
        return comp;
    }

    public static void main(String[] args){
        Fenetre fen = new Fenetre(tcr);
        fen.setVisible(true);
    }
}

I'm fighting with the above code. Could you please explain to me what is wrong and how to resolve the lines not changing color.

Upvotes: 2

Views: 208

Answers (2)

RealSkeptic
RealSkeptic

Reputation: 34618

The reason your solution is not working is that there is actually no connection between the JTable that you create and your Fenetre object in its capacity as a TableCellRenderer. That means your method is never actually called.

But TableCellRenderer is not really meant to be used like this. It is meant to provide the component for other rendering methods to be used. A better approach would be to override the prepareRenderer() method. That method is given the (default) TableCellRenderer, can take the component from it, and then give it the color it wants.

Here is Marc Nuri's implementation of exactly what you are asking for - alternate rows in alternating colors.

Note that he is avoiding coloring the currently selected row by checking if its current background is the selection background. I think a better approach is to query the selection (and also checking isPaintingForPrint()). So my suggestion for your case is to replace the line:

    JTable tableau = new JTable(data, title);

with:

   JTable table = new JTable(data,title){
        public Component prepareRenderer(TableCellRenderer renderer, int row, int column){
            Component returnComp = super.prepareRenderer(renderer, row, column);

            if ( ! isRowSelected(row) || isPaintingForPrint()){
                Color bg = (row % 2 == 0 ? Color.RED : Color.BLUE );
                returnComp.setBackground(bg);
            }
            return returnComp;
        }
    };

Upvotes: 1

dic19
dic19

Reputation: 17971

There are two problems with your code:

  1. You set a new DefaultTableCellRenderer to the table's columns instead of this. Note that your Fenetre class is the one overriding getTableCellRendererComponent(...) method in order to change cells background color.

  2. Your getTableCellRendererComponent(...) implementation delagates the job to create a renderer component to tcr class member, which is a TableCellRenderer and is not initialized. So you'll get a NullPointerException

How to solve it?

Just provide a correct TableCellRenderer implementation. I wouldn't make the class implement the interface directly, I'd get rid of tcr class member and I'd provide a DefaultTableCellRenderer overriding getTableCellRendererComponent(...) like this:

DefaultTableCellRenderer renderer = new DefaultTableCellRenderer() {
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        if ((row % 2) == 0) { // Ligne paire
            comp.setBackground(Color.RED);
        } else { // Ligne impaire
            comp.setBackground(Color.BLUE);
        }
        return comp;
    }
};

renderer.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);

tableau.getColumn("Type").setCellRenderer(renderer);
tableau.getColumn("Utilisateur").setCellRenderer(renderer);
tableau.getColumn("Etat").setCellRenderer(renderer);
tableau.getColumn("Ecran").setCellRenderer(renderer);

Upvotes: 5

Related Questions