1

On my JTable, I am setting the background colors of the rows using the prepareRenderer function. I also removed the focus border and later in the code I disable the row selection.

JTable table = new JTable() {
    private static final long serialVersionUID = -2965586838134675413L;
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component c = super.prepareRenderer(renderer, row, column);
        c.setBackground(row % 2 == 1 ? Color.WHITE : new Color(255, 245, 248));
        ((JComponent) c).setBorder(null);
        return c;
    }
};

DefaultTableModel tableModel = new DefaultTableModel(sampleData, headers) {
    private static final long serialVersionUID = 9186050244728809804L;

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch(columnIndex) {
            case 0:
                return Boolean.class;
            default:
                return String.class;
        }
    }


    @Override
    public boolean isCellEditable(int row, int column) {
        switch(column) {
            case 0:
                return true;
            default:
                return false;
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public void setValueAt(Object aValue, int row, int column) {
        if (aValue instanceof Boolean && column == 0) {
            //System.out.println(aValue);
            Vector<Boolean> rowData = (Vector<Boolean>) getDataVector().get(row);
            rowData.set(0, (boolean) aValue);
            fireTableCellUpdated(row, column);
        }
    }
};

table.setModel(tableModel);
table.setRowSelectionAllowed(false);

The problem is when I click on the JCheckBoxes in the background color switches to white while the mouse button pressed down. Is there a way keep to keep the color from changing whilst clicking on the JCheckBox?

Note
Using the default boolean renderer to achieve this still has the same problem but it does not happen as often

private class BooleanRenderer extends JCheckBox implements TableCellRenderer
{
    private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

    public BooleanRenderer() {
        super();
        setHorizontalAlignment(JLabel.CENTER);
        setBorderPainted(true);
    }

    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        if (isSelected) {
            setForeground(table.getSelectionForeground());
            super.setBackground(table.getSelectionBackground());
        } else {
            setForeground(table.getForeground());
            setBackground(table.getBackground());
        }
        setSelected((value != null && ((Boolean)value).booleanValue()));
        setBorder(noFocusBorder);

        return this;
    }
}

table.setDefaultRenderer(Boolean.class, new BooleanRenderer())

Note 2
I also tried adding a MouseListener to the JCheckBox but that did not work as the mouse listener did not seem to attach to the JCheckBox

JTable fileList = new JTable() {
    private static final long serialVersionUID = -2965586838134675413L;
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component c = super.prepareRenderer(renderer, row, column);
        c.setBackground(row % 2 == 1 ? Color.WHITE : new Color(255, 245, 248));
        ((JComponent) c).setBorder(null);

        if(c instanceof JCheckBox) {
            c.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    setBackground(row % 2 == 1 ? Color.WHITE : new Color(255, 245, 248));
                }

                public void mousePressed(MouseEvent e) {
                    setBackground(row % 2 == 1 ? Color.WHITE : new Color(255, 245, 248));
                }

                public void mouseReleased(MouseEvent e) {
                    setBackground(row % 2 == 1 ? Color.WHITE : new Color(255, 245, 248));
                }
            });
        }
        return c;
    }
};

Edit - SSSCE using first example of code

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

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class JTableTest extends JFrame {
    private JTableTest()  {
        super("Button Layout");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridLayout(1, 1));
        createPanel();
        pack();
        setVisible(true);
    }

    JPanel panel = new JPanel(new GridLayout(1, 1));
    JScrollPane scroll = new JScrollPane();

    private void createPanel() {
        Object[] headers = {"Select", "Title", "Artist", "Length"};
        Object[][] sampleData = {{true, "Bat Outta Hell", "Meat Loaf", "673"},
                {false, "Spanish Train", "Chris De Burgh", "358"}};
        JTable table = new JTable() {
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                c.setBackground(row % 2 == 1 ? Color.WHITE : Color.RED);
                ((JComponent) c).setBorder(null); //Left in so it is easier to see problem
                return c;
            }
        };

        DefaultTableModel tableModel = new DefaultTableModel(sampleData, headers) {
            @Override
            public Class<?> getColumnClass(int columnIndex) {
                switch(columnIndex) {
                    case 0:
                        return Boolean.class;
                    default:
                        return String.class;
                }
            }
        };

        table.setModel(tableModel);
        table.setRowSelectionAllowed(false); //Left in so it is easier to see problem

        scroll.getViewport().add(table);
        panel.add(scroll);
        getContentPane().add(panel);
    }

    public static void main(String[] args) {
        new JTableTest();
    }
}
Dan
  • 7,286
  • 6
  • 49
  • 114
  • 1
    For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Nov 20 '16 at 15:43
  • @AndrewThompson Included. Sorry about that. I thought the JTable code was enough. Do you any ideas on what could be causing it? – Dan Nov 20 '16 at 16:10
  • @Dan Perhaps you should trim the other parts now that you included an SSCCE. – TT. Nov 20 '16 at 16:58
  • An MCVE / SSCCE should include imports & (for a run-time problem) compile cleanly and run to display the error *without any modification.* It should also be a single copy/paste, so have only one class (with main method) declared public with the other classes pasted in at the end of it. – Andrew Thompson Nov 20 '16 at 17:03
  • @AndrewThompson It does unless you're referring to the `*`s in which case I will edit – Dan Nov 20 '16 at 17:04
  • @AndrewThompson Any better? Also any suggestions on how to fix? Would appreciate it – Dan Nov 20 '16 at 17:11
  • @TT. Any better? Also any suggestions on how to fix? Would appreciate it – Dan Nov 20 '16 at 17:12
  • 1
    *Any better?"* It's now an MCVE / SSCCE, so yes. *"Also any suggestions on how to fix?"* What the ..huh? I don't understand yet what is causing the behaviour this example demonstrates. If I have any inspirations, I'll get back to you. – Andrew Thompson Nov 20 '16 at 17:19
  • 1
    Title vs question mismatch. You meant JCheckBox in the title? – TT. Nov 20 '16 at 17:39
  • @TT. Thank you for pointing that out. – Dan Nov 20 '16 at 17:40

1 Answers1

1

You are missing a prepareEditor override in your JTable instance, I added one in your sample. When you click on the checkbox, what is displayed is the editor component rather than the renderer component. You need to prepare that component as well to get the coloring you want.

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

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

@SuppressWarnings("serial")
public class JTableTest extends JFrame {
    private JTableTest()  {
        super("Button Layout");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridLayout(1, 1));
        createPanel();
        pack();
        setVisible(true);
    }

    JPanel panel = new JPanel(new GridLayout(1, 1));
    JScrollPane scroll = new JScrollPane();

    private void createPanel() {
        Object[] headers = {"Select", "Title", "Artist", "Length"};
        Object[][] sampleData = {{true, "Bat Outta Hell", "Meat Loaf", "673"},
                {false, "Spanish Train", "Chris De Burgh", "358"}};
        JTable table = new JTable() {
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                c.setBackground(row % 2 == 1 ? Color.WHITE : Color.RED);
                ((JComponent) c).setBorder(null); //Left in so it is easier to see problem
                return c;
            }

            @Override
            public Component prepareEditor(TableCellEditor editor, int row, int column) {
                Component c = super.prepareEditor(editor, row, column);
                c.setBackground(row % 2 == 1 ? Color.WHITE : Color.RED);
                ((JComponent) c).setBorder(null); //Left in so it is easier to see problem
                return c;
            }
        };

        DefaultTableModel tableModel = new DefaultTableModel(sampleData, headers) {
            @Override
            public Class<?> getColumnClass(int columnIndex) {
                switch(columnIndex) {
                    case 0:
                        return Boolean.class;
                    default:
                        return String.class;
                }
            }
        };

        table.setModel(tableModel);
        table.setRowSelectionAllowed(false); //Left in so it is easier to see problem

        scroll.getViewport().add(table);
        panel.add(scroll);
        getContentPane().add(panel);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater (
            new Runnable() {
                @Override
                public void run() {
                    new JTableTest();
                }
            }
        );
    }
}
TT.
  • 15,774
  • 6
  • 47
  • 88
  • Thank you very much – Dan Nov 20 '16 at 18:36
  • Out of interest do you have any insight on [this](http://stackoverflow.com/questions/40698612/setting-jtableheader-holder-background-colour) – Dan Nov 20 '16 at 18:58