Change the header color of a Alarm Status Table

Does anyone know how to change the color of a table header? Currently it always appears white.
Thanks

If you’re referring to the Perspective Alarm Status Table header, you’ll need to directly modify your custom theme to change this appearance.

.alarmstatustable .ia_table__headContainer {
	background-color: #BBBBBB;
}

Modifying this property in a browser resulted in the header taking on the supplied color, though I have not actually tested this in a theme file.

Hi,
Thanks for you answer but I’m developping in Vision. You know how do that in vision?
Thanks

You would need to drill into the inner table, nested inside the component, and modify its header renderer(s). There's nothing directly exposed. Some reading:

Just for reference, I could set the Alarm Status Header font size and color using the following syntax:

from java.awt import Font
largeFont = Font(“Dialog”, Font.BOLD, 24)
myObject = event.source.parent.getComponent(‘Alarm Status’)
myObject.getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(5).getComponent(0).setFont(largeFont)
myObject.getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(5).getComponent(0).foreground = system.gui.color(255,0,0)

Hi PGriffith,

Hope you have a good day. I try to change the background of the alarm banner header and am not able to find the right place… I can change the background of selection header or the left and footer and a lot of background on the banner actually… But not the default White of the header… Can you show me what I miss… My version of Ignition is 8.1.18. Maybe its with gridColor but I can’t see where is the right gridColor of this components

Best regard Gabriel.

The header background is probably controlled by the Look and Feel. Look into the UIManager class and the client properties: Synthetica - Java Look And Feel

@dkhayes117 may have customized this before, or perhaps @mazeyrat; I don’t readily know what keys to use or if it’s even possible.

Hi w.mandelli, I would like to increase the font size of the label column in an AlarmStatusTable in Vision.

I don't understand how you manage the getComponent arrays, could you please explain me?

Thank you very much.

Hi Aiasa21,
first of all I’m referring to the Alarm Status Table for the Vision Module.

With the syntax in my previous post, I could set the font “Dialog”, Font.BOLD, 24 for the entire header of the Alarm Status Table.

To get a running example, you simply need to paste the script in button on the same window where you have the Alarm Status Table (check and fix if needed the name of the Alarm Status Table component).

I’ve not tried to change the font of one column only

To drill the Alarm Status Table and discover the existing component start from here:
https://forum.inductiveautomation.com/t/alarm-status-table-change-the-ack-button-font-size/14471/11

1 Like

This question is probably interesting and unique enough to be split off into its own topic. I looked at it briefly using an approach that is similar to the one recommended by @w.mandelli, but so far, I haven't found a solution. Below is the code I developed to get the label column along with a list of all of its declared 'get' methods. If nothing else, it will save you a step:

labelColumnFinder Source Code
def labelColumnFinder(alarmStatusTable):
	if alarmStatusTable.componentCount > 0:
		for component in alarmStatusTable.getComponents():
			if 'AlarmStatusTable$1' in str(component.__class__):
				for column in range(component.columnCount):
					if 'Label' in component.getColumnName(column):
						labelColumn = component.getColumnModel().getColumn(column)
						print "Class = " + str(type(labelColumn))
						print "width = " + str(labelColumn.getWidth())
						for index, listener in enumerate(labelColumn.getPropertyChangeListeners()):
							print "listener #" + str(index) + " = " + str(listener)
						print "minimum width = " + str(labelColumn.getMinWidth())
						print "preferred width = " + str(labelColumn.getPreferredWidth())
						print "maximum width = " + str(labelColumn.getMaxWidth())
						print "idnetifier = " + str(labelColumn.getIdentifier())
						print "cell renderer = " + str(labelColumn.getCellRenderer())
						print "model index = " + str(labelColumn.getModelIndex())
						print "header value = " + str(labelColumn.getHeaderValue())
						print "cell editor = " + str(labelColumn.getCellEditor())
						print "header renderer = " + str(labelColumn.getHeaderRenderer())
						print "resizable? = " + str(labelColumn.getResizable())
			labelColumnFinder(component)
alarmStatusTable = event.source.parent.getComponent('Alarm Status Table')
labelColumnFinder(alarmStatusTable)
Source Code Output
Class = <type 'javax.swing.table.TableColumn'>
width = 157
listener #0 = javax.swing.table.DefaultTableColumnModel@665cd340
listener #1 = com.jidesoft.grid.JideTable$15@7839c001
minimum width = 15
preferred width = 75
maximum width = 2147483647
idnetifier = Label
cell renderer = None
model index = 22
header value = Label
cell editor = None
header renderer = None
resizable? = True

To change the font for one specific column, I suspect that at some level, a listener is going to have to be removed to prevent the column from inheriting the font from one of its higher level components. There is also a cellRendererPane associated with this table that could possibly affect this effort in some way. The default column itself doesn't have its own renderer or editor, so it's possible that they will need to be created from scratch and subsequently set.

Thanks to all of you for the help.

It looks like it's more difficult than expected, at this point I prefer having two different pages so to manage them differently without being crazy.

Thanks again and have a nice day.

Today, I developed a dark mode for the alarm status table, and indeed, the header was a bit tricky. The top right corner can be set directly, but to change the header itself, I ended up setting it's background to transparent, so the underlying color could come through. The top left corner underneath the multistate button is a buffered image, so I ended up having to create a graphic to paint over it.
Here is the result:

Here is the full code for dark mode in a version that was set up on the actionPerformed event handler of a test button located in the same container as the table:

Original Source Code
from java.awt import Color

#Sets Footer Color
event.source.parent.getComponent('Alarm Status Table').getComponent(0).background = Color(57,56,61)

#Colors the divider at the right side of the footer
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(1).getComponent(1).background = Color(57,56,61)

#Acknowledge Button Color
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(1).getComponent(0).getComponent(0).background = Color(57,56,61)

#Shelve Button Color
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(1).getComponent(0).getComponent(1).background = Color(57,56,61)

#Colors the gridlines and any uncovered background for the table
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(0).getComponent(0).background = Color(57,56,61)

# Allows header to inherit the background color of the underlying panel
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(0).getComponent(0).getTableHeader().setOpaque(False)

#Sets the font color of the header row
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(0).getComponent(0).getTableHeader().setForeground(Color(248,248,248))

#Sets the background color for the header
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(5).getComponent(0).background = Color(57,56,61)

#Colors the alarm selection buttons
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(3).getComponent(0).background = Color(57,56,61)

#Colors the multiselect button itself in the top left corner
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(4).getComponent(0).background = Color(57,56,61)

#Colors the top right corner
event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(0).getComponent(1).getComponent(0).background = Color(57,56,61)		

#Paints the corner behind the multiselect box in the top left of the table
corner = event.source.parent.getComponent('Alarm Status Table').getComponent(0).getComponent(0).getComponent(1).getComponent(0).getComponent(4)
corner_Field = corner.getClass().getDeclaredField('corner')
corner_Field.setAccessible(True)
corner_Value = corner_Field.get(corner)
graphics = corner_Value.createGraphics()
graphics.setPaint(Color(57,56,61))
graphics.fillRect (0, 0, corner_Value.getWidth(), corner_Value.getHeight())

Edit: Encountered a scenario where the original source code didn't work due to a variation in the way the table was structured that resulted in a "No Child 5" error
Here is a generic version that should work no matter how the table is structured:

Revised Source Code
def setDarkMode(alarmStatusTable):
	from java.awt import Color
	if alarmStatusTable.componentCount > 0:
		for component in alarmStatusTable.getComponents():
			try:
				component.foreground = Color(248,248,248)
			except:
				pass
			try:
				component.background = Color(57,56,61)
			except:
				pass
			try:
				component.getTableHeader().setOpaque(False)
				component.getTableHeader().setForeground(Color(248,248,248))
			except:
				pass
			try:
				corner = component
				corner_Field = corner.getClass().getDeclaredField('corner')
				corner_Field.setAccessible(True)
				corner_Value = corner_Field.get(corner)
				graphics = corner_Value.createGraphics()
				graphics.setPaint(Color(57,56,61))
				graphics.fillRect (0, 0, corner_Value.getWidth(), corner_Value.getHeight())
			except:
				pass
			setDarkMode(component)
alarmStatusTable = event.source.parent.getComponent('Alarm Status Table')
setDarkMode(alarmStatusTable)
2 Likes

To make the above example more specific to this post, I developed it a little further, so the code only affects the header.

Here is the code:

from java.awt import Color
from com.jidesoft.swing import TristateCheckBox, JideScrollPane
from com.inductiveautomation.factorypmi.application.components import AlarmTableHeader
#==============================
#Define Colors
headerBackground = Color.blue
headerForeground = Color.white
checkboxColor = Color.white
#==============================
def setHeaderStyle(alarmStatusTable):
	if alarmStatusTable.componentCount > 0:
		for component in alarmStatusTable.getComponents():
			if isinstance(component, TristateCheckBox):
				component.background = checkboxColor
			if isinstance(component, AlarmTableHeader) or isinstance(component, JideScrollPane):
				component.background = headerBackground
			try:
				component.getTableHeader().setOpaque(False)
				component.getTableHeader().foreground = headerForeground
			except:
				pass
			try:
				corner = component
				corner_Field = corner.getClass().getDeclaredField('corner')
				corner_Field.setAccessible(True)
				corner_Value = corner_Field.get(corner)
				graphics = corner_Value.createGraphics()
				graphics.setPaint(headerBackground)
				graphics.fillRect (0, 0, corner_Value.getWidth(), corner_Value.getHeight())
			except:
				pass
			setHeaderStyle(component)
alarmStatusTable = event.source.parent.getComponent('Alarm Status Table')
setHeaderStyle(alarmStatusTable)

Here is the result:
image

1 Like

Thank you for your good work it's very appreciated :smiley:

1 Like