Search code examples
javaswingjtabletablecellrenderer

How to still view Cell color of selected row in a JTable?


Lets say a JTable has rows with various cell colors like this.

enter image description here

If the first 2 rows are highlighted, it looks like the following and now the colors seen for the first two rows are lost.

enter image description here

Is it possible to make the highlighted rows more transparent so that the underlying colors are still visible? Something similar to what Excel does. Notice the same 2 rows are highlighted and yet the colors are still visible while its still obvious the rows are highlighted/selected.

enter image description here

Here is a modified sample I pulled from the Java2 page and modified it for the above example.

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

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;

class EvenOddRenderer implements TableCellRenderer 
{

  public static final DefaultTableCellRenderer DEFAULT_RENDERER = new DefaultTableCellRenderer();

  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) 
  {
      Component renderer = DEFAULT_RENDERER.getTableCellRendererComponent(table, value,
      isSelected, hasFocus, row, column);
      Color foreground = Color.red, background = Color.WHITE;
      
      if (column == 1 && row == 0) 
      {
          background = Color.GREEN;
      }
      else if (column == 1 && row == 1) 
      {
          background = Color.CYAN;
      }
      else if (column == 1 && row == 2) 
      {
          background = Color.ORANGE;
      }
      else if (column == 2)
      {
          background = Color.YELLOW;
      }

      if (isSelected)
          background = Color.LIGHT_GRAY;

    renderer.setForeground(foreground);
    renderer.setBackground(background);
    return renderer;
  }
}
public class CellColorTransparency {
  public static void main(String args[]) {

    final Object rowData[][] = { 
        { "1", "one",  "I" },
        { "2", "two",  "II" },
        { "3", "three", "III" }};
    final String columnNames[] = { "#", "English", "Roman" };

    final JTable table = new JTable(rowData, columnNames);
    JScrollPane scrollPane = new JScrollPane(table);

    table.setDefaultRenderer(Object.class,new EvenOddRenderer());    
    
    JFrame frame = new JFrame("Color Test Table");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.add(scrollPane, BorderLayout.CENTER);

    frame.setSize(300, 150);
    frame.setVisible(true);

  }
}

Solution

  • It was actually easier than expected.

    Simply use the darker() call within the Renderer.

          if (isSelected)
          background = background.darker();//Color.LIGHT_GRAY;