• Post Reply Bookmark Topic Watch Topic
  • New Topic

Conditional Color Change on JTable  RSS feed

 
Sam Zheng
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I need to add a conditional check for data entered in a JTable. Whenever user enters a data that is bigger than a specified one, the corresponding table cell changes color.
I am thinking to implement the conditional check in the setValueAt() method of TableModel as this method is called whenever data is entered. However, from the setValueAt() method in TableModel, I don't have a way to control the appearance of the table.
Please help!
Sam
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No... if you want to affect the appearance of the table you are going to write a new TableCellRenderer...

For the functionality you want, you can just extend DefaultTableCellRenderer and in the getTableCellRendererComponent() method you would have some code that did something like this...



You could also make a class that encapsulated the "value > 10" test and make the renderer for that class, then you could make a method that tests the value to see if it is in range, and your if statement could use that method... something like "if ( value.isValidValue() )" or whatever you decide to call this method.
 
Sam Zheng
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Nathan!
I have tried the following without success. Could you please help?
First, I implement a tablecellrenderer as below:
public class MyTableCellRenderer implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
TableCellRenderer defaultTableCellRenderer = new DefaultTableCellRenderer();
Component c = defaultTableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(((Double)value).doubleValue() > 10)
c.setForegroung(Color.red);
return c;
}
}
Then, in my JTable, I call the following:
myTable.setDefaultRenderer(Object.class, new MyTableCellRenderer());
Once I compile and run, I found out that the function getTableCellRendererComponent in MyTableCellRenderer is never called whenever I type in any number on the table.
What went wrong?
Thanks!
Sam
[ July 26, 2003: Message edited by: Sam Zheng ]
 
Abhik Sarkar
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Sam,
I don't know if you are still having this problem, but I had a similar problem when I wanted a CellRenderer for an e-mail client which would show me Bold for unread messages, plain for read messages, color highlighting based on sender, etc.
I did the following.
1. Create a new Class MyJTable which extended JTable.
2. Have a member variable of the type MyTableCellRenderer in that class say cellRenderer. This was written in a way similar to what you have written.
3. Override the getCellRenderer method of JTable as follows:

Also, note that you might also have to do something similar for a CellEditor if you want to have different colors and all while editing.
Hope this helps,
Abhik.
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since you are only interested in using your table cell renderer for Doubles, you should register it like this on the table :



Otherwise, you are going to get a ClassCastException when a String or something gets passed to your renderer... it's casting value to Double directly...

Also, another thing that may be giving you a problem is the getColumnClass( int col ) method of your TableModel... you may need to override this method to return the actual classes used in your table.
[ July 28, 2003: Message edited by: Nathan Pruett ]
 
Sam Zheng
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nathan,
When I first tried it, I did use what you suggested below:
myTable.setDefaultRenderer( Double.class, new MyTableCellRenderer() );
Since it didn't work, I registered it with Object hoping that it may. But it didn't either. BTW, in my TableModel, the getColumnClass(int col) does return Double.class.
It really baffles me that the MyTableCellRenderer() never get called! I set a breakpoint at the first valid statement of this class, and it never stops there. Any other thoughts?
I will try Abhik's suggestion later to see whether it works.
Any other suggestions are welcome and appreciated!
Sam
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just took another look at your TableCellRenderer...

it should look like this :


Though the code as it is actually works creating a new DefaultTableCellRenderer inside the method is really bad...

Not sure why you're not getting it to work... it did for me...
 
Abhik Sarkar
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nathan,
Thanks for pointing out that the CellRenderer should be registered for a particular data type...
I had forgotten to mention that the CellRender I wrote used a JLabel and was capable of handling all the possible data types that would be displayed by the table... that's why I overridden the method to return only my CellRenderer.
Thanks,
Abhik.
 
Sam Zheng
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, Nathan.
It works. I don't know why my previous approach didn't work. Looking at the implementation, I find out that my table cell renderer implements
TableCellRenderer interface, while yours extends DefaultTableCellRenderer.
Maybe this makes all the difference.
Sam
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!