0

I'm trying to implement mouse hover effects for my JTable. (When the mouse goes over a table's row the row's background changes).

In order to do that, I extended the DefaultTableCellRenderer like this:

public class FileTableCellRenderer extends DefaultTableCellRenderer{

public FileTableCellRenderer() {
    setOpaque(true);        
}

public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    FileTable fileTable = (FileTable)table;     

    Component c = super.getTableCellRendererComponent(fileTable, value, isSelected, hasFocus, row, column);

    if(!isSelected){
        if(row == fileTable.getCursorRow())
        {           
            c.setBackground(Color.pink);
            c.setForeground(Color.darkGray);
        }
        else
        {
            c.setBackground(Color.white);
            c.setForeground(Color.darkGray);
        }           
    }       

    this.setText(value.toString());

    return this;
}
}

I set the JTable's defaultRenderer, and it works. The problem is I have one column which is Boolean. before I set my renderer I had this cute checkbox as default renderer for it.

Now, it just shows "true" or "false".

On the other hand, if I leave the defualt BooleanRenderer for the Boolean column, it will not be highlighted with the whole row...

I also tried to extned the JTable.BooleanRenderer, but it seems to be protected, so I cannot even extend it.

How can I leave this checkbox of the BooleanRenderer, but change background color with the rest of the row?

user1028741
  • 2,745
  • 6
  • 34
  • 68
  • Set your own renderer, and make what you want .. or you can have by composition a BooleanCellRenderer, first call BooleanCellRenderer#getTableCellRendererComponent and then with your implementation.. – nachokk Sep 27 '13 at 19:11
  • please for why reson is there needed (unknow and probably buggy) BooleanRenderer, maybe I can't found any reason, or am I wrong .... – mKorbel Sep 27 '13 at 19:13
  • it will not be highlighted with the whole row... == use prepareRenderer – mKorbel Sep 27 '13 at 19:14

1 Answers1

1

This cannot be done using inheritance since BooleanRenderer is a non-public inner class of JTable. But you can use composition instead. E.g., create a wrapper class that will accept a TableCellRenderer ('parent') as a constructor argument. If you pass a BooleanRenderer from your table as a parent, calling its getTableCellRendererComponent() method will return a Checkbox component, so you'll be able to make any further adjustments to it (I use code from the question to set the background color):

import javax.swing.*;
import javax.swing.plaf.UIResource;
import javax.swing.table.TableCellRenderer;
import java.awt.*;

public class BooleanCellRenderer implements TableCellRenderer, UIResource {

    private final TableCellRenderer parent;

    public BooleanCellRenderer(TableCellRenderer parent) {
        this.parent = parent;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component c = parent.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        FileTable fileTable = (FileTable) table;
        if (!isSelected) {
            if (row == fileTable.getCursorRow()) {
                c.setBackground(Color.pink);
                c.setForeground(Color.darkGray);
            } else {
                c.setBackground(Color.white);
                c.setForeground(Color.darkGray);
            }
        }
        return c;
    }
}

Then, in your main GUI class containing a JTable, take the table's default Boolean renderer and pass it to the wrapper:

FileTable fileTable = new FileTable();
fileTable.setDefaultRenderer(Boolean.class, new BooleanCellRenderer(fileTable.getDefaultRenderer(Boolean.class)));

You can leave the FileTableCellRenderer to render String cells:

FileTable fileTable = new FileTable();
fileTable.setDefaultRenderer(String.class, new FileTableCellRenderer());
fileTable.setDefaultRenderer(Boolean.class, new 
Denis Abakumov
  • 355
  • 3
  • 11