Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX Secondary Screen "Always on Top" of All Applications

I've read about using a JDialog to wrap a JFXPanel in order to use JDialog's alwaysOnTop method. It works, but I'm having a small issue with this hack.

Since I'm using this technique to make secondary windows to my main application (popups etc), I need to set them on top of the main window. If I use the wrapper hack to do this, the top panel is "always on top" of everything (including other applications).

Is there a way to put the secondary screen only on top of my application? I don't like the fact that another application can be dragged in between the main window and secondary window of my application.

like image 570
Matt Avatar asked Apr 05 '13 06:04

Matt


2 Answers

I suggest not using JDialog and JFXPanel, but only using JavaFX Stages.

Make your secondary screen a Stage and invoke secondaryStage.initOwner(primaryStage) before you show the secondary stage.

From the Stage documentation:

A stage can optionally have an owner Window. When a window is a stage's owner, it is said to be the parent of that stage . . . A stage will always be on top of its parent window.

I believe setting the owner of the secondary stage, correctly fulfills your requirement of "secondary screen only on top of my application".


Update: answers to additional questions from comments

I don't want there to be any interaction with the main stage once the secondary is open (the secondary window must be closed to allow interaction again).

To block input to the primary stage, Before showing the secondary stage, call: secondaryStage.initModality(Modality.WINDOW_MODAL).

You could use APPLICATION_MODAL instead of WINDOW_MODAL if you preferred to block all input to any other of your application windows - which one to use depends on the user experience you want.

There's nothing obvious in the api that would center the secondary screen on the main screen. It just always centers on the monitor, no matter where the main screen is.

This part of the question is a duplicate of Center location of stage. The answer to the duplicate has sample code for performing the centering of the child window.

That's right, there is nothing in the public api around positioning child windows relative to parent windows. I've filed a feature request for this functionality Add helper methods for positioning popups relative to nodes, but the feature request has not yet been implemented as of JavaFX 2.2.

There is a sample project I created to do relative positioning of child dialogs, which might be useful.

Just for centering within the parent, you are probably best off querying the stage location and width before displaying the child and then setting the x and y co-ordinates of the child appropriately when you display it. All of this can be done based on x, y and width properties of windows.

There is also a dialog project in the JavaFX UI controls sandbox which might provides some of the functionality you require so that you don't need to code it yourself.

In time all of the functionality you are requesting will probably end up in the JavaFX core platform, but I don't think it's all quite there yet for JavaFX 2.2.

like image 84
jewelsea Avatar answered Nov 01 '22 23:11

jewelsea


I agree with jewelsea, but if you need to use JDialog and JavaFX stages (like it was my case), then you can't set your primaryStage's parent or modality.

The only solution i found is to use a little "hack":

I use JNA, Java Native Access API to do my own setAlwaysOnTop() method using User32.INSTANCE.setWindowPos(...) with HWND_TOPMOST parameter.

edit: see microsoft doc and jna doc

like image 38
Flo C Avatar answered Nov 02 '22 00:11

Flo C