# Component Inspector on KeyPressed

**URL:** <https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692>\
**Category:** Ignition\
**Tags:** sdk, scripting\
**Created:** [January 23, 2018, 2:12pm UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692 "2018-01-23T14:12:26Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![thijs1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/thijs1/32/14793_2.png) [@thijs1](https://forum.inductiveautomation.com/u/thijs1)\
**Post date:** [January 23, 2018, 2:12pm UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692/1 "2018-01-23T14:12:26Z")

</div>

Hi,

I’m trying to implement a Component inspector that displays all references tagPaths on the component beneath the current mouseposition. It seems to work for simple bindings. But when I test this on Templates, it doesn’t give me any results. Could somebody point me in the right direction to inspect Template Bindings? Any suggestions are very welcom

Right now I came up with this in a Keypressed (shift - F10) script:

```auto
from com.inductiveautomation.factorypmi.application import VisionDesktop
from com.inductiveautomation.factorypmi.application.binding import AbstractPropertyAdapter
from com.inductiveautomation.factorypmi.application.binding import AbstractTagAdapter
from com.inductiveautomation.factorypmi.application.binding import ExtensibleBinding
from com.inductiveautomation.factorypmi.application.binding import SQLPropertyAdapter
from com.inductiveautomation.factorypmi.application.binding import TagHistoryAdapter
from com.inductiveautomation.factorypmi.application.binding import ExpressionPropertyAdapter
from com.inductiveautomation.factorypmi.application.binding import IndirectTagBindingAdapter

window = system.nav.desktop(VisionDesktop.CURRENT_DESKTOP.get()).getCurrentWindow()
oWindow = system.gui.getWindow(window)
point = oWindow.mousePosition	
x = int(point.getX())
y = int(point.getY())

component = oWindow.findComponentAt(x,y)

adapters = oWindow.interactionController.getAllAdaptersForTarget(component)

str_list = []
str_list.append("COMPONENT : " + component.getName())

for a in adapters :
	str_list.append( "---------------------------ADAPTERS-------------------------------------")
	str_list.append( "PROPERTY: " + a.getTargetPropertyName() )
	if (isinstance(a, AbstractPropertyAdapter)) :
		str_list.append( 'TARGET : ' + str(a.getTargetFullPath()))
		str_list.append( 'PROP : ' + str(a.getTargetPropertyName()) )
		str_list.append( 'VALUE : ' + str(a.getQValue().getValue()))
	if (isinstance(a,AbstractTagAdapter)) :
		str_list.append( 'TAG : ' + a.getTagPathString() )
	if (isinstance(a,ExtensibleBinding)) :
		str_list.append( 'ExtensibleBinding : ' + str(a.getParameters()) )
	if (isinstance(a,SQLPropertyAdapter)) :
		str_list.append( 'SQL Datasource : ' + str(a.getDatasource()) )
		pullQuery = a.getPullQuery()
		if pullQuery != None :
			str_list.append( 'SQL PULL Query : ' + str(pullQuery.getQuery()) )
		pushQuery = a.getPushQuery()
		if pushQuery != None :
			str_list.append( 'SQL PUSH Query : ' + str(a.getPushQuery().getQuery()) )
	if (isinstance(a,TagHistoryAdapter)) :
		for historicalPath in a.getPathList():
			str_list.append( 'PathListItem : ' + str(historicalPath.getAlias()) )
	if (isinstance(a,ExpressionPropertyAdapter)) : 
		str_list.append('Expression: ' + str(a.getExpressionSource()))

system.gui.messageBox( "\n".join(str_list))

```

Thanks !

---

<div class="post-metadata">

**Author:** ![thijs1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/thijs1/32/14793_2.png) [@thijs1](https://forum.inductiveautomation.com/u/thijs1)\
**Post date:** [January 29, 2018, 11:25am UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692/2 "2018-01-29T11:25:08Z")

</div>

Any suggestions anybody ?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 29, 2018, 1:22pm UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692/3 "2018-01-29T13:22:37Z")

</div>

I don’t have an answer for your question itself, but you might want to investigate what exactly you’re getting from findComponentAt(). The various template holders are layered components and you might not be getting a result from fCA() at the nesting level you think. Consider enumerating and printing the parent chain of the returned component up to the enclosing window. (With a recursion limit – you never know.)

---

<div class="post-metadata">

**Author:** ![thijs1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/thijs1/32/14793_2.png) [@thijs1](https://forum.inductiveautomation.com/u/thijs1)\
**Post date:** [January 29, 2018, 1:47pm UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692/4 "2018-01-29T13:47:30Z")

</div>

Hi Phil,

Thank you for your answer!

The type of the object I get is for example : com.inductiveautomation.factorypmi.application.components.PMILabel . So I guess I’m getting the AWT / Swing component here. What I can’t figure out is to get from this AWT component to the Template ?

Kind regards,  
Thijs

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 29, 2018, 2:13pm UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692/5 "2018-01-29T14:13:43Z")

</div>

Let me repeat:

> [@pturmel](#):
>
> Consider enumerating and printing the parent chain of the returned component up to the enclosing window.

You need to see the hierarchy before you'll be able to algorithmically identify the desired components.

---

<div class="post-metadata">

**Author:** ![c.day](https://avatars.discourse-cdn.com/v4/letter/c/ea666f/32.png) [@c.day](https://forum.inductiveautomation.com/u/c.day)\
**Post date:** [January 30, 2018, 4:17pm UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692/6 "2018-01-30T16:17:13Z")

</div>

Two possibilities:

1. I think getComponentAt() returns the top-level component, while findComponentAt() returns the child. [Link](https://docs.oracle.com/javase/7/docs/api/java/awt/Container.html#findComponentAt(java.awt.Point)) If your template is at the top level, perhaps use get instead of find.

2. If your template is not at the top level, you could use findComponentAt() and recursively search up through the parents. Here’s a script I put on a mouse button’s mouse click event.

```auto
def compInfo(window, comp):
	# If this is not the top-level component, try again on the parent
	if comp.getParent() != window.getRootContainer():
		return compInfo(window, comp.getParent())
	
	#Do all of your stuff to get component adapters here
	adapters = "foo"
	
	str = comp + " has adapters " + adapters
	return str

oWindow = system.gui.getParentWindow(event)
point = oWindow.mousePosition	
x = int(point.getX())
y = int(point.getY())
component = oWindow.findComponentAt(x,y)

print; print
print compInfo(oWindow, component)

```

If the component is the top-level component on the screen (direct child of the root container), it will print that component’s adapters. If the component is a child of something else, it will go up through its parents until it gets to whatever is a direct child of the root container.

You’ll probably have to tweak your search through the parents for your particular case, perhaps looking at the type of the parent to see when you reach a template. Things might get tricky if you have templates inside templates, or templates inside groups.

Side note: I haven’t confirmed, but you should be able to do `oWindow.findComponentAt(point)` without having to separate your point into x and y.

---

<div class="post-metadata">

**Author:** ![c.day](https://avatars.discourse-cdn.com/v4/letter/c/ea666f/32.png) [@c.day](https://forum.inductiveautomation.com/u/c.day)\
**Post date:** [January 30, 2018, 5:11pm UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692/7 "2018-01-30T17:11:13Z")

</div>

Third idea: Perhaps use `oWindow.getComponentAt(point)` to get the top-level component. Then recursively look for children using `component.getComponentAt(point)` method on each child, stopping the first time you find a component that has adapters you’re looking for.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 30, 2018, 6:10pm UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692/8 "2018-01-30T18:10:17Z")

</div>

> [@c.day](#):
>
> Then recursively look for children using component.getComponentAt(point) method on each child

If you go this route, you'll have to adjust the point at every level. I'd keep using Java's nicely-optimized findComponent() and then climb the parent tree to find the desired component type.

---

<div class="post-metadata">

**Author:** ![c.day](https://avatars.discourse-cdn.com/v4/letter/c/ea666f/32.png) [@c.day](https://forum.inductiveautomation.com/u/c.day)\
**Post date:** [January 30, 2018, 8:02pm UTC](https://forum.inductiveautomation.com/t/component-inspector-on-keypressed/16692/9 "2018-01-30T20:02:18Z")

</div>

The code for converting the point should be a single line, though I don’t know how efficient it is.

```auto
from javax.swing import SwingUtilities

SwingUtilities.convertPoint(parentComponent, point, childComponent)

```

If @thijs1’s script is doing what I think it does, I believe you’ll ultimately want the highest-level component with adapters. You could use `find` to get the child, work your way up to build the list of all parents, then go through your list to find the highest-level parent that meets your needs. Or you could start at the top with `get`, work your way down (converting points as you go), and stop when you reach the first one that meets your needs. I don’t know which method would be better.

I don’t have access to Ignition at the moment to try anything out, but I think this is something I want to use as well. If I make any progress with it, I’ll report back.
