IAmYourFaja
IAmYourFaja

Reputation: 56914

Changing Swing JTable Cell Colors

I'm trying to get comfortable with JTables, TableModels, JTableHeaders, renderers, etc. I am trying to make a simple dummy table (for practice purposes) that looks like this:

-    1    2   3
A    A1   A2  A3
B    B1   B2  B3
C    C1   C2  C3

I also want the B2 cell - and only that cell - to have a blue (Color.BLUE) background - all other cells can have the Swing default color they are assigned automagically.

My code is below and is based off countless examples I have found on this website and the internet at large. But I am not getting the results I want. Instead I'm getting a table that looks like this:

A    A1   A2  A3
B    B1   B2  B3
C    C1   C2  C3

Notice that the first row (the header) isn't there at all. Additionally, with the code I list below, this executes and sets the color of all the cells that color, not just the B2 cell that I want.

The code:

public class MyTable
{
    public static void main(String[] args)
    {
        String[][] data = getTableData();
        String[] cols = getTableCols();

        JFrame frame = magicallyCreateJFrame();     // I promise this works!
        MyRenderer myRenderer = new MyRenderer();   // See below

        DefaultTableModel defModel = new DefaultTableModel(data, cols);
        JTable myTable = new JTable(defModel);

        myTable.setDefaultRenderer(Object.class, myRenderer);

        frame.add(myTable);
        frame.pack();
        frame.setVisible(true);            
    }
}

public static String[] getTableCols()
{
    String cols =
    {
        "-",
        "1",
        "2",
        "3",
    };
}

public static String[][] getTableData()
{
    String[][] data =
    {
        {
            "A",
            "A1",
            "A2",
            "A3",
        },
        {
            "B",
            "B1",
            "B2",
            "B3",
        },
        {
            "C",
            "C1",
            "C2",
            "C3",
        },
    };

    return data;
}

And the quick-n-dirty MyRenderer class:

public class MyRenderer extends DefaultTableCellRenderer  
{ 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean   isSelected, boolean hasFocus, int row, int column) 
{ 
    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 

    if(row == 2 && column == 2)
        c.setBackground(new java.awt.Color(0, 0, 255)); 

    return c; 
} 

} 

Besides the fact that this is horrible code and breaks a lot of "best practices"-type patterns and techniques (remember this is just something I'm playing around with), is there anything I'm doing here that is glaringly-obvious? Why am I not getting a table header (first row "- 1 2 3")? Why is my default cell renderer not working on the specific B2 cell I am specifying?

JTables seem to be strange, beautiful and powerful beasts. I'm slowly wrapping my mind around them but am choking on the implementation. Thanks to any that can help!

Upvotes: 6

Views: 30248

Answers (5)

Mateva
Mateva

Reputation: 812

I believe the correct way to do table colouring is via a ColorHighlighter. I have given an example here.

Upvotes: 0

camickr
camickr

Reputation: 324118

You need to make sure you reset the renderer to its default background color (and handle row selection):

if (! table.isRowSelected(row))
{
    if(row == 2 && column == 2)
        c.setBackground(new java.awt.Color(0, 0, 255));
    else
        c.setBackground(table.getBackground());
}

In the future post a proper SSCCE with your question.

Upvotes: 15

ChrisJ
ChrisJ

Reputation: 5251

Half-answer:

You need to put your JTable inside a JScrollPane to have the header displayed. Or alternatively you can manually add to the layout the component returned by myTable.getTableHeader(). I recommend using a JScrollPane though.

EDIT:

As suggested below, to turn the background blue for just one specific cell, all you need to do is add a test like this one:

if(column == 2 && row == 1) {
    c.setBackground(Color.BLUE); 
} else {
    c.setBackground(Color.WHITE);
}

Upvotes: 4

umbr
umbr

Reputation: 440

Perhaps, myTable.setDefaultRenderer(String.class, myRenderer); would work correct.

Upvotes: 0

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

Where do you specify the renderer to color B2 and only B2? Perhaps you want to place an if block in your getTableCellRendererComponent method so that the background color is set to blue only if the JTable's value object's toString() is "B2" or if the row and column values correspond to the B2 cell.

And to see your table header, you should first add the table to a JScrollPane and then add the JScrollPane to the parent.

Most important: read the Swing tutorials on JTables as this is all explained in there.

Upvotes: 3

Related Questions