简体   繁体   中英

custom DefaultTableCellRenderer not changing the background color of row on jTable

I'm trying to fill my table from an ArrayList andd using a custom DefaultTableCellRenderer to render it:

public class CustomRender extends DefaultTableCellRenderer {
    private ArrayList<Color> desiredColors = new ArrayList<Color>();

    public void setColors(Color incomingColor)
    {
        desiredColors.add(incomingColor);
    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        for (int i = 0; i < desiredColors.size(); i++) {
            cellComponent.setBackground(desiredColors.get(i));
        }
        return cellComponent;
    }
}

And I'm using it this way

CustomRender colouringTable = new CustomRender();

DefaultTableModel model = new DefaultTableModel(){
    public boolean isCellEditable(int rowIndex, int mColIndex) {
        return false;
    }
}; 

table = new JTable(model);
JScrollPane scroller = new JScrollPane(table);

model.addColumn("ID"); 
model.addColumn("Username"); 
model.addColumn("Departement"); 

for (Employee e: Departement.employees) {
    model.addRow(new Object[]{String.valueOf(e.userId), e.username, e.departement});
    if (e.chef) {
        colouringTable.setColors(Color.RED); 
    } else {
        colouringTable.setColors(Color.GREEN); 
    }
}

for (int i = 0; i < table.getColumnCount(); i++) {
    table.getColumnModel().getColumn(i).setCellRenderer(colouringTable);
}

But for some reason, none of the rows are red nor green, it's not changing any colors. Can anyone point out what I'm doing wrong?

You're not using cell renderers correctly. Currently your code fills an ArrayList, desiredColors, with colors, when filling the JTable's model, and then iterating through that list within the renderer, but that simply makes no sense since all cells will simply be given the color of the last color held by the ArrayList.

Instead what you want to do is give the renderer the two colors, perhaps in its constructor, and within the renderer's getTableCellRendererComponent method, test the data in the table, as obtained by the value parameter, and use that information to set the renderer's color.

eg,

class MyRenderer extends DefaultTableCellRenderer {
    private Color chefColor;
    private Color defaultColor;

    public MyRenderer(Color chefColor, Color defaultColor) {
        this.chefColor = chefColor;
        this.defaultColor = defaultColor;
        setOpaque(true);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
        Component superComp = super.getTableCellRendererComponent(table, value, isSelected,
                hasFocus, row, column);

        // here test if row holds a chef item
        // if so, set background color to chefColor
        // otherwise set background color to the defaultColor.
        return superComp;
    }
}

For example:

import java.awt.Color;
import java.awt.Component;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

/**
 * Example of using a DefaultTableModel that holds a row of specific type
 * Example of hidden column determining color of cells
 * @author Pete
 *
 */
@SuppressWarnings("serial")
public class SimpleTableExampe extends JPanel {
    RestaurantEmployee[] employees = {
            new RestaurantEmployee("John", true, 1),
            new RestaurantEmployee("Bill", false, 2),
            new RestaurantEmployee("Sally", true, 3),
            new RestaurantEmployee("Frank", false, 4),
            new RestaurantEmployee("Jim", false, 5),
            new RestaurantEmployee("Imelda", true, 6)
    };
    private MyTableModel tableModel = new MyTableModel();
    private JTable table = new JTable(tableModel);

    public SimpleTableExampe() {
        MyRenderer renderer = new MyRenderer(Color.RED, Color.GREEN);
        for (int i = 0; i < table.getColumnCount(); i++) {
            table.getColumnModel().getColumn(i).setCellRenderer(renderer);
        }
        add(new JScrollPane(table));
        for (RestaurantEmployee employee : employees) {
            tableModel.addEmployee(employee);
        }        
    }

    private static void createAndShowGui() {
        SimpleTableExampe mainPanel = new SimpleTableExampe();

        JFrame frame = new JFrame("SimpleTableExampe");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

class RestaurantEmployee {
    private String name;
    private boolean chef;
    private int id;

    public RestaurantEmployee(String name, boolean chef, int id) {
        this.name = name;
        this.chef = chef;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public boolean isChef() {
        return chef;
    }

    public int getId() {
        return id;
    }

    @Override
    public String toString() {
        return "RestaurantEmployee [name=" + name + ", chef=" + chef + ", id=" + id + "]";
    }
}

@SuppressWarnings("serial")
class MyTableModel extends DefaultTableModel {
    private static final String[] COLUMN_NAMES = { "Name", "ID" };

    public MyTableModel() {
        super(COLUMN_NAMES, 0);
    }

    public void addEmployee(RestaurantEmployee employee) {
        addRow(new RestaurantEmployee[] { employee });
    }

    @Override
    public int getColumnCount() {
        return COLUMN_NAMES.length;
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        if (getRowCount() > 0) {
            return getValueAt(0, columnIndex).getClass();
        } else {
            return super.getColumnClass(columnIndex);
        }
    }

    public RestaurantEmployee getEmployee(int row) {
        return (RestaurantEmployee) super.getValueAt(row, 0);
    }

    @Override
    public Object getValueAt(int row, int column) {
        RestaurantEmployee employee = (RestaurantEmployee) super.getValueAt(row, 0);
        switch (column) {
        case 0:
            return employee.getName();
        case 1:
            return employee.getId();        
        default:
            return null;
        }
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return false;
    }

}

@SuppressWarnings("serial")
class MyRenderer extends DefaultTableCellRenderer {
    private static final int ALPHA = 60;
    private Color chefColor;
    private Color defaultColor;

    public MyRenderer(Color chefColor, Color defaultColor) {
        this.chefColor = chefColor;
        this.defaultColor = defaultColor;
        setOpaque(true);
        setHorizontalAlignment(SwingConstants.CENTER);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
        Component superComp = super.getTableCellRendererComponent(table, value, isSelected,
                hasFocus, row, column);
        if (value != null) {
            MyTableModel tableModel = (MyTableModel) table.getModel();
            boolean chef = tableModel.getEmployee(row).isChef();
            Color c = chef ? chefColor : defaultColor;
            if (!hasFocus && !isSelected) {
                c = new Color(c.getRed(), c.getGreen(), c.getBlue(), ALPHA);
            } 

            superComp.setBackground(c);
        }
        return superComp;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM