I have a West docked window that expands/collapses based on mouse movement. Works great except for one small issue… it doesn’t always close. I have a script on the root container event ‘mouseExited’ which slides the window closed when the mouse exceeds the bounds of the docked container. However, if the mouse is moved really fast, then this event does not register and the window stays open until you move your mouse over the bounds again.
Question is: Is there a way to script when a root container loses focus? Or, is there another reliable way to assure the menu closes when the mouse is moved off it?
What if you put a script in the other window’s root container’s mouseEntered function to close the docked window. That might capture the event better, you might even have the script in both as extra insurance. Scripting on the window itself, not the root container, has the internalFrameDeactivated function that fires when a window loses focus, but I don’t think moving your mouse out the frame causes focus loss, you would have to click out of the frame.
Thanks dkhayes, I appreciate the response. I had actually tried the mouseEntered method previously on a single screen. As expected it worked, but I was not a fan of this method as it would entail adding a script on about 150 screens. Ugh… So that is why I was wondering about the ‘focus lost’ scripting on a root container. When I get a chance to try the internalFrameDeactivated method on the internal window I will post back if successful.
Here is some code where i did something close. Put this on the propertyChange of the rootContainer on the window you want to collapse/expand.
from javax.swing import SwingUtilities
from java.awt.event import AWTEventListener, MouseEvent
from java.awt import AWTEvent, Toolkit, MouseInfo
from java.awt import IllegalComponentStateException
from java.awt.dnd import DragSourceMotionListener, DragSource
from com.inductiveautomation.ignition.client.util.gui import IgnitionSwingUtilities
from com.inductiveautomation.factorypmi.application import FPMIWindow
class GlobalMouseListener(AWTEventListener):
def __init__(self, container):
self.container = container
def startup(self):
Toolkit.getDefaultToolkit().addAWTEventListener(self, AWTEvent.MOUSE_EVENT_MASK)
Toolkit.getDefaultToolkit().addAWTEventListener(self, AWTEvent.MOUSE_MOTION_EVENT_MASK)
def shutdown(self):
Toolkit.getDefaultToolkit().removeAWTEventListener(self)
def isMousePointInPanel(self, point):
x = point.x
y = point.y
location = self.container.getLocationOnScreen()
cx = location.getX()
cy = location.getY()
cw = self.container.getWidth()
ch = self.container.getHeight()
return x <= cx + cw and x >= cx and y < cy + ch and y >= cy
def handleEnterExit(self, point):
if self.isMousePointInPanel(point):
# here is where your expand logic goes
print 'Mouse in Panel'
pass
else:
# here is where the contract logic goes i would set a contracted flag here to save time.
print 'Mouse not Panel'
pass
def eventDispatched(self, event):
try:
point = event.getLocationOnScreen()
container_window = IgnitionSwingUtilities.getAncestorOfClass(FPMIWindow, self.container)
if event.getID () == MouseEvent.MOUSE_MOVED:
self.handleEnterExit(point)
except IllegalComponentStateException:
pass
if event.propertyName == 'componentRunning':
if event.newValue:
listener = GlobalMouseListener(event.source)
listener.startup()
event.source.putClientProperty('global_listener', listener)
else:
listener = event.source.getClientProperty('global_listener')
listener.shutdown()
Thank you for the code!! It’s exactly what I was looking for, and works flawlessly. I really tried to trip it up with all kinds of mouse movement and could not. I really appreciate your time and expertise! Kudos!