So I have been looking all over the forums and even though there are solutions for Modal pop-up windows, it doesn’t look like any of them work for me. I have a variety of pop-up windows that all need to be able to lock out the user from selecting any and all background buttons.
Pop-up window with layer greater than it’s called window.
The best example I have found is the 2-State Toggle Button with Confirm. The Confirmation Pop-Up has the exact feature I need to prevent any and all clicks to the background (docked or otherwise). How can I implement this? Custom Jython script in my script library? Any other recommendations?
The auto-logout function (which I cannot find where it exists) is pretty nifty and has some of the same features as well (locks input other than message box and grays-out the background). I also noticed the “Prevent Popup/Docking Overlap” option in Project Properties. I might uncheck that to see what happens.
That works if the button only does one thing. I need a pop-up that has 2-3 buttons and associated tags being changed. E.g. Up/Down/Stop, On/Off, Increase1/Increase2/Decrease1/Decrease2, and it gets even more complicated. The goal is to get the pop-up to have the same focus and immutability as that confirm dialog box.
Sadly, the default popup is a sort of internal frame (you can notice it has a different border than the confirm popup). It doesn’t seem to be a real popup, but just some sort of floating component inside the screen that always stays on top.
Here is what I came up with, as I have been trying to acompolish the same. I started with the popup with opaque approach you linked. Then on my popup open and close events I set a client tag boolten to indicate a modal is open. In any docked windows, I then used that tag to enable an overlay. Only problem is that I can still click events in the docked windows, thats the last thing to figure out how to disable.
One rabbit-hole I may try: A client tag called DisableButtons. This tag is set 1 when a pop-up opens and 0 when it gets closed. All buttons on the screen utilize the DisableButtons in it’s Enabled property… Messy, but possible. Another thought is to ignore mouse pushes/clicks if it is outside of the pop-up window’s boundaries. Less messy, but more code (that could be reused).
Just messing around. I combined the opaque pop-up method (below) with the following setLocation code in the script area internalFrameActivated.
from java.awt import Color
event.source.setOpaque(0)
window = system.gui.getParentWindow(event)
window.setLocation(-20,-70)
setLocation fires after I open the window again. Odd. I wonder if there is another event handler I could use instead (I tried internalFrameOpened to same effect)
This might get complicated, but here is how I have achieved this in the past.
As an example, I will use my custom lock screen, attached in this post.
Here is the script.
def lockScreen():
from javax.swing import SwingUtilities,JFrame #Import some stuff
import system.nav
if system.util.getGlobals().has_key('lockScreen'): #Check if the screen has been locked before. This really just saves the set up code
system.util.getGlobals()["app"].getRootPane().getGlassPane().visible = True #Make the glass pane visible
system.util.getGlobals()["lockScreen"].visible = True #Make the lock screen visible
else:
lockScreen = system.nav.openWindow('Lock Screen') #Open the lock screen once. To get a reference to the window
system.util.getGlobals()["lockScreen"] = lockScreen #Set a global variable referencing that instance
app = SwingUtilities.getAncestorOfClass(JFrame, lockScreen) #Get the app pane
system.util.getGlobals()["app"] = app #Set a reference to the app pane
system.nav.closeWindow('Lock Screen') #Close the window. We have a reference now
lockScreen.setDefaultCloseOperation(lockScreen.DISPOSE_ON_CLOSE) #Set window close action
app.getRootPane().getGlassPane().visible = True #Make the glass pane visible
app.getRootPane().getGlassPane().add(lockScreen) #Add the custom screen to the glass pane
lockScreen.visible = True #Make the window visible.
The main thing you have to change here is the window you open for the lockScreen. This window will open in the glass pane, covering everything else. How you decorate the window is up to you.
This is code I had in FPMI, so from when I was first learning Python. I will see if I can clean it up.
Create a modal dialog with opaque background as described here.
Create a Client Boolean tag called ‘modal’.
Create your docked window, then create a container the full size of the docked window and move it to the top of the z-order. Set the container’s Opaque property to false and bind it’s Visibility property to the modal Client tag. In the container’s mouseClicked, mousePressed and mouseReleased’ events enter pass to consume the mouse clicks.
When you open and close your popup make sure you set and clear the modal tag.
This should ensure you can still see all controls under the popup but cannot click on any of them. I also like to put a tint on the popup background and container to focus attention on the popup.
So you want to create a popup window that users can’t click off of and stays above the parent window? Sorry, not really familiar with the term.
Here’s what I came up with:
The first part would be clicking on the popup window and setting the layer above the layer of the parent window. That should keep it on top of the parent until the user closes the window. It won’t filter clicks though, we’ll get to that.
Then turn off close-able so the X doesn’t display at the top. Turn off resizeable, and turn off maximizable.
Then in internal frame deactivated for the popup make it center the window using the script builder (make sure it doesn’t open another instance). Go into the script editor and do. This make the window recenter and refocus if the user clicks off. You probably want to make sure the window always caches.
try:
list(system.gui.getOpenedWindows()).index(‘WINDOWNAME’)
centerthewindow()
except:
“” #If you don’t do this when you close the window but click something else the popup will reopen.
Then on frame activated open a second popup window with a layer higher than the root container but not higher than the popup we want. No titlebar or border, with an invisible transparent root container. This will sponge clicks off of our modal window. You can add a Windows ding with system.util.beep(), if you so wish. (Please don’t.).
For our modal window we want to open and close our invisible window on the InternalFrame ActivatedDeactivated of our modal window.
I would try and do something with binding the name to the root container so you don’t have to change the window name in the scripts every time you want to re-use it.
If you want to Cellophane over the other window or whatever:
You need to make the root container of your click blocker window an opaque color, and then in the visionWindowOpened put this script in.
All great suggestions, but I may not have been clear enough. I already have it working for the main window in which the pop-up occurs. What I don’t have is when there is a tabbed navigation and a main window (e.g. Single-Tier Nav, West), I cannot make the pop-up “cover” or disable the clicking of the navigation bar (as my video sort-of shows).
I’ll dig into Kyle_Chase’s example later, but I don’t want to get too deep into Swing as other maintenance users down the line will not be able to fix any issues on-site (KISS methodology).
Ah I see. For my solution I’m thinking getOpenedWindows() and then adding the size of all the docked windows and sizing the transparent blocker window based on that, instead of maximizing the window. In theory it should cover all docked navigation and windows.
Just had need to do this and achieved it using information from this thread as well as others. It “greys out” and prevents clicking on all other windows except docked windows (for me, that’s not a huge drama as the only dock I have is the navigation bar, and I’m fine with the user switching windows behind the scenes; they can’t do anything with them except look)
Set the Layer of the modal popup to 99
Create a popup window called “Focus Mask”. Set it to start maximised, never display title bars or borders, and to a size larger than your largest display (I set mine to 1920x1080). Set the Layer of this window to 98
On the Focus Mask window’s root container, set the visible property to True, and the background colour to be partially opaque
On the Focus Mask Window, add the following script to the VisionWindowOpened trigger:
window=system.gui.getParentWindow(event)
window.setOpaque(0)
5 . On the modal popup, use a VisionWindowOpened script to open the “Focus Mask” window, and a VisionWindowClosed script to close the “Focus Mask” window