# Button Events Within Templates

**URL:** <https://forum.inductiveautomation.com/t/button-events-within-templates/14382>\
**Category:** Ignition\
**Created:** [May 23, 2017, 9:37pm UTC](https://forum.inductiveautomation.com/t/button-events-within-templates/14382 "2017-05-23T21:37:25Z")\
**Posts on this page:** 4\
**Page:** 2

<div class="post-metadata">

**Author:** ![chris3145](https://avatars.discourse-cdn.com/v4/letter/c/96bed5/32.png) [@chris3145](https://forum.inductiveautomation.com/u/chris3145)\
**Post date:** [April 10, 2019, 3:53pm UTC](https://forum.inductiveautomation.com/t/button-events-within-templates/14382/21 "2019-04-10T15:53:39Z")

</div>

@tarun89engg, Java Swing runs the innermost event. If a parent component has a mousePressed script, but a child inside that parent has a mouseEntered script, any time your mouse is over both the child **and** the parent, only the child’s mouse events will be run.

That means if you have mouse events on both the parent and child, you need to program the scripts on the child to somehow invoke the scripts on the parent. A straightforward way to do that is by having a mouse event on the child finish by invoking the same mouse event on its parent.

* * *

I have a button template where mouse events exist inside the template, but like @Kyle_Chase, I also want to be able to write scripts on template instances (so somebody can place the template and code a script on it in **exactly** the same way they would with a regular button). For that, I accomplish the same thing he did in the following way:

The five mouse events on the child component have scripts that do whatever the child component needs them to do, but the scripts always finish with this:

```auto
template = event.source.parent
template.passEventToInstance(event)

```

The passEventToInstance() custom method looks like this:

```auto
	from javax.swing import SwingUtilities
	
	btn = self.parent
	convertedEvent = SwingUtilities.convertMouseEvent(event.source, event, btn)
	btn.dispatchEvent(convertedEvent)

```

As the name suggests, SwingUtilities.convertMouseEvent() converts a mouse event on one component into a mouse event on another component (e.g. a mousePressed event on the child component would be converted to a mousePressed event on the parent). SwingUtilities has the added benefit of converting the event coordinates, so the location of the event should still work out correctly if the parent cares about that. The btn.dispatchEvent() function invokes the newly-converted event on that component (i.e. it makes that new mousePressed event on the parent actually “happen”).

---

<div class="post-metadata">

**Author:** ![tarun89engg](https://avatars.discourse-cdn.com/v4/letter/t/ecb155/32.png) [@tarun89engg](https://forum.inductiveautomation.com/u/tarun89engg)\
**Post date:** [April 11, 2019, 6:03am UTC](https://forum.inductiveautomation.com/t/button-events-within-templates/14382/22 "2019-04-11T06:03:41Z")

</div>

@chris3145  
Thanks for your clear explanation.  
Now the concept is clear to me.

---

<div class="post-metadata">

**Author:** ![mlindstrom](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mlindstrom/32/30000_2.png) [@mlindstrom](https://forum.inductiveautomation.com/u/mlindstrom)\
**Post date:** [July 30, 2020, 5:17pm UTC](https://forum.inductiveautomation.com/t/button-events-within-templates/14382/23 "2020-07-30T17:17:02Z")

</div>

This was super helpful! Note by default, buttons add an `action/actionPerformed` script rather than one of the five mouse events (i.e. if you use the UI to automatically generate a script to open a popup window). This cannot be passed up to the parent template instance, which does not have `action/actionPerformed` scripts but only mouse events. Trying anyway causes an error due to type mismatching (`java.awt.event.ActionEvent` rather than type `java.awt.event.MouseEvent`).

However, it’s easy enough to move the actionPerformed script into a mouse event script instead, and this got it working for me. Thank you!!!

---

<div class="post-metadata">

**Author:** ![JHortenberry](https://avatars.discourse-cdn.com/v4/letter/j/b3f665/32.png) [@JHortenberry](https://forum.inductiveautomation.com/u/JHortenberry)\
**Post date:** [March 4, 2021, 6:40pm UTC](https://forum.inductiveautomation.com/t/button-events-within-templates/14382/24 "2021-03-04T18:40:08Z")

</div>

Attempting to extend the above approach to PropertyChange:

To support PropertyChange, the following were added to the imports:

from javax.swing import SwingPropertyChangeSupport

Currently, the firePropertyChange() triggers the following error:

Error:

```
Caused by: org.python.core.PyException: Traceback (most recent call last):
File "<event:propertyChange>", line 8, in <module>
File "<custom-function passEventToInstance>", line 15, in passEventToInstance
AttributeError: type object 'java.beans.PropertyChangeEvent' has no attribute 'firePropertyChange'

```

Docs indicate a firePropertyChange(PropertyChangeEvent evt) method:  
[https://docs.oracle.com/javase/7/docs/api/javax/swing/event/SwingPropertyChangeSupport.html](https://docs.oracle.com/javase/7/docs/api/javax/swing/event/SwingPropertyChangeSupport.html)

Code:

Template / Numeric Text Field / propertyChange

```
if event.propertyName == 'value':
     template = event.source.parent
 template.passEventToInstance(event)                    

```

Template / Custom Method / passEventToInstance

```
def passEventToInstance(self, event):
     from java.beans import PropertyChangeEvent

     ntf = self.parent
     convertedEvent = SwingPropertyChangeSupport.firePropertyChange(event.source, event)
     ntf.dispatchEvent(convertedEvent)	

```

The Goal:

When the Numeric Text Field (within the template instance) value change event occurs, re-trigger the event at the (Template) Instance level to add additional functionality.

Insights?

Previous Post - Excellent!

[Previous page](https://forum.inductiveautomation.com/t/button-events-within-templates/14382.md?page=1)
