Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1065
  • Last Modified:

Swing: Change background color of a JTable cell

Please let me know how I can change the color of a cell of a JTable.
I have a table that represents a schedule of tasks to be performed by somebody. When a task's start time (I can retrieve this information) exceeds the current time, the background color must change automatically.

Thanks!
0
dshrenik
Asked:
dshrenik
  • 6
  • 5
  • 2
4 Solutions
 
for_yanCommented:

You can use CustmCellRenderer
http://download.oracle.com/javase/tutorial/uiswing/components/table.html#renderer

It will return cComponent adn you'll be able to set background based on
the row and cell, so you will need to check it from time to time and when you know that process started for cetrain cell it should return component
with another color
0
 
RinilCommented:
hi,

PFA a sample code that does simple table background change.


ColorRenderer.java
0
 
RinilCommented:
Missed to include the main class
please put these 2 classes in same package and run

TableRowColor2.java
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
dshrenikAuthor Commented:
@for_yan:
I wan't able to entirely follow the explanation on the link you provided.
If possible, can you give some sample code? Thanks!
0
 
for_yanCommented:
I simplified (and a little bit mutilated) the code of Rinil to show you how
to color one cell in the JTable - I think this will give
you what you want.
I think it can be done evven easier not
column by coilumn - I'll try to do it
but this shows how it works also

So, when you dicover that your cell at certain row and column needs to be colred
you just execute these lines again:

   ColorRenderer cr=new ColorRenderer(2,1);


         table.getColumnModel().getColumn(0).setCellRenderer(cr);
             table.getColumnModel().getColumn(1).setCellRenderer(cr);
             table.getColumnModel().getColumn(2).setCellRenderer(cr);
             table.getColumnModel().getColumn(3).setCellRenderer(cr);


this is the whole code:


import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;

public class TableRowColor2 extends JFrame
    {
     public TableRowColor2()
         {
             JTable table=new JTable(new DefaultTableModel(new Object[][]{
             {"1","2","3","4"},
             {"2","3","4","5"},
             {"3","4","5","6"},
         {"4","5","6","7"}},
         new Object[]{"A","B","C","D"}));
        
         ColorRenderer cr=new ColorRenderer(2,1);
        
         //Adding this line of code will color only the first column and different colors for
         //each row and dont forget to comment the for loop


         table.getColumnModel().getColumn(0).setCellRenderer(cr);
             table.getColumnModel().getColumn(1).setCellRenderer(cr);
             table.getColumnModel().getColumn(2).setCellRenderer(cr);
             table.getColumnModel().getColumn(3).setCellRenderer(cr);



         JScrollPane scroll=new JScrollPane(table);
         this.setContentPane(scroll);
         this.setBounds(100,50,300,150);
     }
     public static void main (String arg[])
         {
         TableRowColor2 tes = new TableRowColor2();
         tes.setVisible(true);
         tes.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     }
}


class ColorRenderer extends JLabel implements TableCellRenderer
    {
     private String columnName;
        int row1;
        int column1;
     public ColorRenderer(int row1, int column1)
         {
         this.row1 = row1;
             this.column1 = column1;
        // this.columnName = column;
         setOpaque(true);
     }
     public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column)
         {
             if (row == row1 && column == column1)setBackground(Color.red);
             else  setBackground(Color.gray);
               /*
         Object columnValue=table.getValueAt(row,table.getColumnModel().getColumnIndex(columnName));

         if (value != null) setText(value.toString());
         if(isSelected)
             {
             setBackground(table.getSelectionBackground());
             setForeground(table.getSelectionForeground());
         }
         else
             {
             setBackground(table.getBackground());
             setForeground(table.getForeground());


             if (columnValue.equals("1")) setBackground(java.awt.Color.pink);
             if (columnValue.equals("2")) setBackground(java.awt.Color.green);
             if (columnValue.equals("3")) setBackground(java.awt.Color.red);
             if (columnValue.equals("4")) setBackground(java.awt.Color.blue);

         }
             */
         return this;
     }
}

Open in new window

0
 
dshrenikAuthor Commented:
Don't we need to call getTableCellRendererComponent(?
0
 
for_yanCommented:




This is even better example - you don't need to
do it column by column

Besides when you execute it you'll see how it fist paint cell (1,1)
then after 5 seconds wit the red color will switch to (2,2)

thus modeling situation which you'll probably need

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

public class TableRowColor2 extends JFrame

    {
         static  JTable table;
     public TableRowColor2()
         {
              table=new JTable(new DefaultTableModel(new Object[][]{
             {"1","2","3","4"},
             {"2","3","4","5"},
             {"3","4","5","6"},
         {"4","5","6","7"}},
         new Object[]{"A","B","C","D"}));

            // table.setDefaultRenderer(Object.class, new ColorRenderer(1,1));

              //  table.setDefaultRenderer(Object.class, new ColorRenderer(2,2));


         JScrollPane scroll=new JScrollPane(table);
         this.setContentPane(scroll);
         this.setBounds(100,50,300,150);
     }
     public static void main (String arg[])
         {
         TableRowColor2 tes = new TableRowColor2();
         tes.setVisible(true);

               table.setDefaultRenderer(Object.class, new ColorRenderer(1,1));
             System.out.println("here 1");
              try{
                           Thread.currentThread().sleep(5000);
             } catch(Exception ex){
                 ex.printStackTrace();
             }
             System.out.println("here 2");
             table.setDefaultRenderer(Object.class, new ColorRenderer(2,2));
             tes.repaint();
             System.out.println("here 3");
         tes.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     }
}


class ColorRenderer extends  DefaultTableCellRenderer
    {
     private String columnName;
        int row1;
        int column1;
     public ColorRenderer(int row1, int column1)
         {
         this.row1 = row1;
             this.column1 = column1;
        // this.columnName = column;
         setOpaque(true);
     }
     public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column)
         {
             if (row == row1 && column == column1)setBackground(Color.red);
             else  setBackground(Color.gray);

         return this;
     }
}

Open in new window

0
 
for_yanCommented:
No, you don't need to call getComponent - that's the baeuty of it - once you registered
the nmethod which will be used to paint the table then Swing when it will be drawin the
table it will call itseklf this method for each cell and draw ithe componment in each cell - you don't need
to call it - Swing will cal it for you.

As you'll see in my latest code the only thing you may need to do is to initiate
repaint of the whol table after you register different cell renderer
which will recognize and paint the new cell
0
 
dshrenikAuthor Commented:
The code works great when I implement them! However, I am not sure why it isnt working when I implement it my existing project.
I am referencing the same ColorRenederer class for both my actual code and the test code (for which it works).
0
 
for_yanCommented:
Well, try to reduce your code to minimal piece which still does not work, but can be posted here (and still is self-standing - can be executed by istelf) - then
when I come back to my computer I can try to debug your code
0
 
dshrenikAuthor Commented:
Can you tell me how I can change the color of a specific cell, without using a rederer? I'll first try if that works!
0
 
for_yanCommented:
I'm not sure how to do it woithoiut renderer - this is why tgey designed renderer to accommodate all different ways of how you want to change the appearnce of cells based on individual cells
0
 
dshrenikAuthor Commented:
The funny thing is that the ColorRenderer is not being called by my table. I added this code to getTableCellRendererComponent():
System.out.println(row + " " + column);

When I run the test code you provided, all the row and column numbers are printed. However, this does not happen for my table!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now