Hi,
Is it possible to customize the Alarm Status Table, f.eks. changig name of colums etc.?
Hi,
Is it possible to customize the Alarm Status Table, f.eks. changig name of colums etc.?
Are you using the Alarm Status Table in Vision or Perspective?
Hi,
I am using the Alarm Status Table in Vision.
I recently developed a way to accomplish this. Here is the code:
def columnLabeler(alarmStatusTable):
if alarmStatusTable.componentCount > 0:
for table in alarmStatusTable.getComponents():
if 'AlarmStatusTable$1' in str(table.__class__):
tableHeaders= table.getTableHeader()
columnModel = table.getColumnModel()
for column in range(table.columnCount):
tableColumn = columnModel.getColumn(column)
tableColumn.setHeaderValue("Custom Column Name " + str(column + 1))
tableHeaders.repaint()
columnLabeler(table)
alarmStatusTable = event.source.parent.getComponent('Alarm Status Table')
columnLabeler(alarmStatusTable)
The code finds the table within the component, and then loops through the columns using normal jtable methods to apply custom headers. This version is written for the actionPerformed event handler of a button in the same container as the Alarm Status Table.
The preceding code produces the following result:
One thing that is interesting about the code is that even if the client hides and reshows the column, the table remembers the replacement name. That said, the code will have to be ran from either an onInternalFrameOpened event script or something that works in this way, because if the window is closed, the table will not remember the next time the window is opened.
Updated header using the list and also this script is written in the same visionWindowOpened event handler (see below screenshot).
def columnLabeler(alarmStatusTable):
lstCustomHeaders = ['Active Time','Current State','Tag Name','Description','Alarm State','Priority','Events','Ack By','Ack Notes']
if alarmStatusTable.componentCount > 0:
for table in alarmStatusTable.getComponents():
if 'AlarmStatusTable$1' in str(table.__class__):
tableHeaders= table.getTableHeader()
columnModel = table.getColumnModel()
for column in range(table.columnCount):
tableColumn = columnModel.getColumn(column)
custColName = lstCustomHeaders[column]
tableColumn.setHeaderValue(str(custColName))
tableHeaders.repaint()
columnLabeler(table)
alarmStatusTable = system.gui.getParentWindow(event).getComponentForPath('Root Container.Alarm Status Table')
columnLabeler(alarmStatusTable)
In the past, I've done many component manipulations using the internalFrameOpened event handler, but I no longer prefer this way. Presently, I prefer to call my scripts from the component they affect using the componentRunning propertyChange event handler:
Example:
if event.propertyName == 'componentRunning`:
#Manipulate the component here
This event handler only runs once when the component is initialized, and perhaps more importantly, it can't run before the component instance exists. Personally, I've never had a problem with running component initialization scripts from internalFrameOpened, but I've seen problems of the aforementioned nature from the visionWindowOpened event handler, so I would be wary of manipulating a component in this manner from there.
Ok, Thank you @justinedwards.jle for the information and your help.
Uploading: Capture d’écran 2024-07-17 125257.png…
where can I put my script
That old script is overdue for a refactor:
# Written for the propertyChange event handler of an alarm status table
# The component running event only fires once when its component is first initialized
# It won't fire in the designer unless preview mode is on prior to opening the window
if event.propertyName == 'componentRunning':
# Returns the first nested component of a given class
# container = The object containing nested components to be recursively searched
# className = the __name__ of the class given as a string
def findComponentOfClass(container, className):
for component in container.components:
if component.__class__.__name__ == className:
return component
else:
foundComponent = findComponentOfClass(component, className)
if foundComponent:
return foundComponent
# Recursively find the inner table
innerTable = findComponentOfClass(event.source, 'AlarmStatusTable$1')
# Iterate through the table columns and conditionally change the header values in some way
columnModel = innerTable.columnModel
for column in xrange(innerTable.columnCount):
tableColumn = columnModel.getColumn(column)
if tableColumn.headerValue == 'Label':
tableColumn.headerValue = 'Custom Alarm Name'
# Repaint the table header
innerTable.tableHeader.repaint()
This script was written for the propertyChange
event handler of the Alarm Status table itself. Simply right click on the alarm status table in the designer. Then, click on "Scripting" in the popup that appears, and place the script in the propertyChange event handler:
Result:
I didn’t get a good result since I want it to just display
Active time , name and ack time
If all you want to do is hide columns, right click on the header, and use the check boxes in the photo that appears. IIRC, this action will be remembered if done in the designer prior to save.
Every time I do an update it comes back to 0 you have to check again and you will do ca for all the drive I want it to remain in default just act time ,akt time é and the name of the alarm and thank you for ten help
I could be reading this wrong, but it seems like you are also wanting to hard code the starting columns at initialization?
It could be done like this:
# Written for the propertyChange event handler of an alarm status table
# The component running event only fires once when its component is first initialized
# It won't fire in the designer unless preview mode is on prior to opening the window
if event.propertyName == 'componentRunning':
# Returns the first nested component of a given class
# container = The object containing nested components to be recursively searched
# className = the __name__ of the class given as a string
def findComponentOfClass(container, className):
for component in container.components:
if component.__class__.__name__ == className:
return component
else:
foundComponent = findComponentOfClass(component, className)
if foundComponent:
return foundComponent
# Recursively find the inner table
innerTable = findComponentOfClass(event.source, 'AlarmStatusTable$1')
# Alarm Status Table column model map:
# Model Index Column Name
# 0 ackNotes
# 1 Ack Time
# 2 Ack'ed By
# 3 Active Pipeline
# 4 Clear Pipeline
# 5 Ack Pipeline
# 6 Active Time
# 7 Clear Time
# 8 Event Value
# 9 Deadband
# 10 Display Path
# 11 Acked?
# 12 Active?
# 13 Clear?
# 14 Name
# 15 Notes
# 16 Priority
# 17 Source Path
# 18 Current State
# 19 Event ID
# 20 Unacknowledged Duration
# 21 Active Duration
# 22 Label
# Define which columns to keep (see map)
startingColumns = [1, 6, 22]
# Unhide all of the columns
innerTable.model.fireTableStructureChanged()
# Get all of the columns from the column model that are not in the starting column list
# ...and remove them
columnModel = innerTable.columnModel
columnsToHide = [columnModel.getColumn(index) for index in xrange(23) if index not in startingColumns]
for column in columnsToHide:
columnModel.removeColumn(column)
# Iterate through the starting columns and customize the names as needed
for column in xrange(innerTable.columnCount):
tableColumn = innerTable.columnModel.getColumn(column)
if tableColumn.headerValue == 'Label':
tableColumn.headerValue = 'Alarm Name'
innerTable.tableHeader.repaint()