Overrides for a Power Table

Could a java guru help a fella out?
We have a few power tables where we need to set row background colors based off of numerous factors.
We cannot use the configureCell extension since we change the underlying dataset on the fly and the column names change along with it.
Could someone post just an example of overriding the renderer based on column values?
Something like below?

JTable table = new JTable(...)
public Component prepareRenderer(
TableCellRenderer renderer, int row, int column)
Component c = super.prepareRenderer(renderer, row, column);

    //  add custom rendering here

    return c;


Hi did you find a solution for this by any chance because I have a similar situation where there are lots of data in power table and using configure cell affects the gui thread

What is your current configureCell script?

import sys

	replacementText=self.data.getValueAt(rowIndex,colIndex) if colIndex != 18 else ''
	bgColor = '255,255,255'
	fgColor = '0,0,0'
	if self.parent.showBW:
		if colName=="Priority" and int(value) == 4 :
			return {'text': 'Critical','background': '255,255,255'}
		if colName=="Priority" and int(value) == 3 :
			return {'text': 'High','background': '255,255,255'}
		if colName=="Priority" and int(value) == 2 :
			return {'text': 'Medium','background': '255,255,255'}
		if colName=="Priority" and int(value) == 1 :
			return {'text': 'Low','background': '255,255,255'}
		if colName=="Priority" and int(value) == 0 :
			 return {'text': 'Diagnostic','background': '255,255,255'}
		return {'background': '255,255,255'}
		if colName=="Priority" and int(value) == 4 :
			 return {'text': 'Critical','foreground': 'White','background': 'Red'}
		if colName=="Priority" and int(value) == 3 :
			 return {'text': 'High','foreground': 'Red','background': 'Yellow'}
		if colName=="Priority" and int(value) == 2 :
			 return {'text': 'Medium','foreground': 'White','background': 'Black'}
		if colName=="Priority" and int(value) == 1 :
			 return {'text': 'Low','foreground': 'Black','background': 'Gray'}
		if colName=="Priority" and int(value) == 0 :
			 return {'text': 'Diagnostic','foreground': 'Black','background': 'White'} 	 	 
		if severity==4 :
			return {'foreground': 'White','background': 'Red'}
		if severity==3:
			return {'foreground': 'Red','background': 'Yellow'}
		if severity==2:
			return {'foreground': 'White','background': 'Black'}
		if severity==1:
			return {'foreground': 'Black','background': 'Gray'}
		if severity==0:
			return {'foreground': 'Black','background': 'White'}
		if colIndex==3:

exc_type, exc_obj, tb = sys.exc_info()
lineno = tb.tb_lineno
error_description=str(lineno)+" , "+str(exc_type)+" , "+str(exc_obj)
print error_description

its this and this is loading the gui thread so much that within each 15-20 secs we are getting a non-responsive UI thread log
unfortunately we have lot of data in power table, like 3000 rows in average and 19 columns, so configure cell is taking too much time

There are a lot of things that don't make much sense in this script.
I'll try to refactor it a bit to make it a bit more sensible, and hopefully make bugs more apparent.

But I have a few questions already:
What's the difference between severity and priority ?
What should be done with replacementText ?
Can the priority/severity be below 0 or above 4 ?

In the end, I guess what we really need to know is: What do you want to do ?

1 Like

@pascal.fragnoud sorry for the confusion, but this script kind of needs a lot of redactions and commenting out of few lines, few trials has been done over this script and I forgot to clean it up before pasting here.

Leave severity and check for the portion which contains priority. Basically in this power table we will be showing alarm details and based on the priority from low to critical(0-4) we will assign a color, there is an column which gives us the priority data and based on that we want to give each row a color

I don't have vision so I can't test things, so I'm kind of shooting in the dark here. That's why I ask questions.

If I'm interpreting correctly, you have a column with the priority code (0 to 4), and this part:

is responsible for changing that code into the text representation ("Low" to "Critical").
Is that right ?
If not, what's the purpose of 'text': "Critical" ?
This does seem strange to me. What happens to cells that are processed after the priority column ?

What is self.parent.showBW and what does it do ?

I have no idea how to color a whole table more efficiently, it seems power tables only have configureCell for this. So you'll have to process every cell if there's no other option.
A complexity of w*h, which is clearly a problem for high values of w and/or h.
If this is taking too long, making the script simpler might help a bit, but the performance improvement will only be very small compared to what could be gained by reducing the complexity.

What else is done in this script ?
Maybe some of it could be offloaded to something else, so that configureCell is only responsible for changing the color. Maybe this could help speed things up a bit, with a simpler script:

priority = int(self.data.getValueAt(rowIndex, priority_column_index))
colors = [
	("Black", "White"),
	("Black", "Gray"),
	("White", "Black"),
	("Red", "Yellow"),
	("white", "Red"),
return {'foreground': colors[0], 'background': colors[1]}

Though building the table for every cell is not ideal, it's probably better than risking branch mispredictions, supposing jython actually builds the list.
Maybe using a project script with a constant table would be better ?

yes your assumptions are right 'text': "Critical" sets the text to critical or atleast I believe it does because another member of my team is working on this, self.parent.showBW is a property which has been set to either true/false using a button, to make the power table black and white instead of using colors by checking priority.
Thanks for the sample script, I will ask my team to try out and will let you know

Update for black and white:

if self.parent.showBW:
	return {'foreground': "black", 'background': "white"}
	priority = int(self.data.getValueAt(rowIndex, priority_column_index))
	colors = [
		("Black", "White"),
		("Black", "Gray"),
		("White", "Black"),
		("Red", "Yellow"),
		("white", "Red"),
	return {'foreground': colors[0], 'background': colors[1]}

ok thanks, will incorporate this one as well

Using qualified constant access to java.awt.Color would be faster than returning strings, which will have to be parsed to colors:

from java.awt import Color
if self.parent.showBW:
	return {'foreground': Color.BLACK, 'background': Color.WHITE}
	priority = int(self.data.getValueAt(rowIndex, priority_column_index))
	fg, bg = [
		(Color.BLACK, Color.WHITE),
		(Color.BLACK, Color.GRAY),
		(Color.WHITE, Color.BLACK),
		(Color.RED, Color.YELLOW),
		(Color.WHITE, Color.RED),
	return {'foreground': fg, 'background': bg}

You could also put your colors list (a dictionary might be faster) in a project script or custom method to avoid allocating a list of tuples for each cell in the table.

got it Paul, will try the dictionary version like you suggested. Just to be clear if I am using a project script, then inside that I should be assigning like-
{'critical':'(Color.WHITE, Color.RED)'} or like {4:'(Color.WHITE, Color.RED)'} right? or did I grasped it in a wrong way?

I believe the above given script itself is neat enough to do the job, but if dictionary can save us some few milliseconds it will help us in the long run, so definitely I want to try that out. Thanks Paul for your support.

I really doubt a dictionary would provide performance gains here.
For now, try the same script (with the list) in a project script. If that's not enough, then try the dictionary variant. Take it one step at a time.

1 Like