Hi Jordan,
Turns out there is a way.
parent = event.source
while parent is not None:
print "=============================="
print parent
print type(parent)
# Get next parent
parent = parent.parent
Ive put this on a button, which prints the entire graphical buildup until your object.
==============================
PMIButton: Print Parent Component Tree
<type 'com.inductiveautomation.factorypmi.application.components.PMIButton'>
==============================
Root Container
<type 'com.inductiveautomation.factorypmi.application.components.BasicContainer'>
==============================
javax.swing.JLayeredPane[null.layeredPane,0,0,1594x900,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true]
<type 'javax.swing.JLayeredPane'>
==============================
javax.swing.JRootPane[,5,22,1594x900,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@11e69176,flags=449,maximumSize=,minimumSize=,preferredSize=]
<type 'javax.swing.JRootPane'>
==============================
winDevTestScreen
<type 'com.inductiveautomation.factorypmi.application.FPMIWindow'>
==============================
VisionApp[Airtec_PRODUCTION]
<type 'com.inductiveautomation.factorypmi.application.FPMIApp'>
==============================
javax.swing.JViewport[,1,1,1851x1028,invalid,layout=javax.swing.ViewportLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=25165832,maximumSize=,minimumSize=,preferredSize=,isViewSizeSet=true,lastPaintPosition=java.awt.Point[x=0,y=0],scrollUnderway=false]
<type 'javax.swing.JViewport'>
==============================
javax.swing.JScrollPane[,0,0,1853x1030,invalid,layout=javax.swing.ScrollPaneLayout$UIResource,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@684ea065,flags=320,maximumSize=,minimumSize=,preferredSize=,columnHeader=,horizontalScrollBar=javax.swing.JScrollPane$ScrollBar[,1,1016,1851x13,hidden,layout=javax.swing.plaf.synth.SynthScrollBarUI,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@5c9f5ee0,flags=4194560,maximumSize=,minimumSize=,preferredSize=,blockIncrement=10,orientation=HORIZONTAL,unitIncrement=1],horizontalScrollBarPolicy=HORIZONTAL_SCROLLBAR_AS_NEEDED,lowerLeft=,lowerRight=,rowHeader=,upperLeft=,upperRight=,verticalScrollBar=javax.swing.JScrollPane$ScrollBar[,1839,1,13x1007,hidden,layout=javax.swing.plaf.synth.SynthScrollBarUI,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@2fb7cea2,flags=4194560,maximumSize=,minimumSize=,preferredSize=,blockIncrement=10,orientation=VERTICAL,unitIncrement=1],verticalScrollBarPolicy=VERTICAL_SCROLLBAR_AS_NEEDED,viewport=javax.swing.JViewport[,1,1,1851x1028,invalid,layout=javax.swing.ViewportLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=25165832,maximumSize=,minimumSize=,preferredSize=,isViewSizeSet=true,lastPaintPosition=java.awt.Point[x=0,y=0],scrollUnderway=false],viewportBorder=javax.swing.plaf.synth.SynthScrollPaneUI$ViewportBorder@219ff1fb]
<type 'javax.swing.JScrollPane'>
==============================
com.inductiveautomation.factorypmi.application.runtime.ClientPanel[,0,27,1853x1030,invalid,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@409d49db,flags=9,maximumSize=,minimumSize=,preferredSize=]
<type 'com.inductiveautomation.factorypmi.application.runtime.ClientPanel'>
==============================
javax.swing.JLayeredPane[null.layeredPane,0,0,1853x1057,invalid,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true]
<type 'javax.swing.JLayeredPane'>
==============================
javax.swing.JRootPane[,8,31,1853x1057,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@617f516c,flags=16777673,maximumSize=,minimumSize=,preferredSize=]
<type 'javax.swing.JRootPane'>
==============================
javax.swing.JFrame[frame1,59,-8,1869x1096,invalid,layout=java.awt.BorderLayout,title=Airtec_PRODUCTION - Development: Test Screen,resizable,maximized,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,8,31,1853x1057,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@617f516c,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
<type 'javax.swing.JFrame'>
Turns out that the <type 'javax.swing.JViewport'> gives the exact width and height without update notifications nor scrollbars.
If you would like to include scrollbars, you can also use <type 'javax.swing.JScrollPane'>.
So to fetch these objects I use your script to go from the root back down to the viewport object as following.
from javax.swing import SwingUtilities
from javax.swing import JScrollPane
# Get component
component = event.source
# Get the root JFrame
root = SwingUtilities.getRoot(component)
# Get the ContentPane (Inside the borders)
contentPane = root.getContentPane()
# Get the inner viewport (Inside the borders and inside the scrollpane)
for component in contentPane.getComponents():
if type(component) == JScrollPane:
viewport = component.getViewport()
viewportSize = viewport.size
viewportWidth = viewportSize.width
viewportHeight = viewportSize.height
print 'Viewport: {} x {}'.format(viewportWidth, viewportHeight)
Do you maybe know if its possible, and how to add some kind of listener to this object that triggers something when the size values change?