JavaFX Secondary Screen "Always on Top" of All Applications - javafx

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.

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.

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

Related

JavaFX nodes - How to make them resizable by the end user?

I am developing a JavaFX application where a class I have developed (extended from javafx.scene.Parent) is created on-the-fly based on what entry the user has clicked in a ListView control.
Just to be clear about this node, it is not created using a layout tool like SceneBuilder, it is created at runtime based on the user's actions.
The constructor for my custom node class creates a VBox and a Label and uses passed coordinates (X,Y) in the constructor method to set its own Layout coords. I then use a custom utility class to make the node draggable. This new node is then added to the main application Pane.
However, I have failed to find out how I can make these nodes resizable by the user. That is, allow the user to mouse over the corner of the node, hold and drag to resize. An operation that all users are used to, no matter what the OS.
Has anyone done anything like this in JavaFX? (My searches on the subject only seem to pull up subjects on the automatic resizing that a parent node does with its child nodes.)
Many thanks,
Ian.
As you can see on the documentation of VBox you can only define minimum, prefered and maximum range, there's not really a way to make it manually resizable.
The only proper solution to solve your problem is to develop your own class to do it, because what you want seems very specific, with your problem description, I don't think use some layouts or panels will do what you exactly want.
I found something that you can use : Dragging to resize a JavaFX Region
This allows you to resize a region, all you have to do after is to put you VBox in this region, but notice in this article that :
Only height resizing is currently implemented.
This code won't work in JavaFX8, you'll have to check the comment to see how it worls in JavaFX8
Hope this helps.

Qt Parent child relationship for independent qmainwindows

Using Pyside, but a general Qt question:
I am building a Qt app with a controlling QMainWindow. From this window the user can open other QMainWindows (or QDialogs) and from some of those she can open more. The user is intended to think of the first QMainWindow as "the app" and the others as lots of different views on more or less the same data.
So I'd like all the windows to be independently stackable so the user can set up the screen to their own requirements. In particular I want the user to be able to bring the first QMainWindow on top if wanted. But I don't really want each window to have its own task bar entry (though I can live with that). Also I would like them to minimise and restore together, and I would like them all to close when the first main window closes.
If I parent them all on the first mainwindow it works nicely except they stay on top of it which is not what I want.
Instead I have it kind of working by making them all independent with parent = None. Then I register them all with the main window and close them all when it closes. But this makes them a bit too independent - they minimise separately and have their own task bar entry.
Am I missing some obvious fix to this? Is there any easy way (a flag?) to stop the children staying on top of the parent?
Or is there some UI guideline that I am breaking by desiring this?
Or is there a cleaner design somehow? I thought of adding a dummy parent that they could all descend from but maybe that's messy. Would that parent need a visual presence? I wouldn't want that.
Suggestions?
You can have as many QMainWindows as you want, or parentless QWidgets. I think the best way to handle your situation is to create your own pseudo parent-child relationship like this:
In your QMainWindow subclass, store a QList of all the QWidgets you want it to manage. Then, again in your QMainWindow subclass, reimplement methods such as QWidget::closeEvent(), QWidget::hideEvent() (for when the window is minimized), and QWidget::showEvent() (for when it is restored) so that it also closes, hides, or shows all of the widgets in its QList. Make sure to also delete them in the QMainWindow subclass's destructor. Now, whenever you create a sub-window, pass the main window a pointer to it not as a normal QWidget child, but just so that it can be added to the main window's QList of QWidgets to manage. E.g.:
MainWindowSubclass::addPseudoChild(QWidget *pseudoChild)
{
myListOfPseudoChildren.append(pseudoChild);
}
Another alternative that hasn't been mentioned yet is populating a QMdiArea with QMdiSubWindows. It doesn't do exactly what you asked for, but it's a pretty clean design nonetheless.
So I thought I would add what I eventually settled upon. This was particularly inspired by the comments of #leemes (Thanks - good stuff) and a little experimentation of my own.
I used the code attached here DetachTabExample
to develop a "Detachable Tab" widget and tab bar. This allows tabs to be dragged outside the main window when they become independent windows. Then if closed they return to the tab bar.
Then I placed all my content in the QMainWindow but in separate tabs. The users can drag the ones they want out on to the other monitor. Seems to be working fine. There are still some extra windows that I have floating but it has cut down the clutter and clarified the structure.

QToolbar force shrink

Qt toolbars shrink and display an 'extend' button when there isn't enough space.
Is there anyway to create a toolbar pre-shrunk? I want to display just the first label so I can use a large number of toolbars as floatable popup-menus (or a linear dialogboxs ).
I specifically want to use toolbars (rather than dialogs) because they are already created for another app.
Internally a class called QToolbarLayout makes this decision about the "extension" button, based on the size of the space the toolbar is given:
http://qt.gitorious.org/qt/qt/blobs/4.7/src/gui/widgets/qtoolbarlayout.cpp#line398
So there's no method or slot for it, beyond setting its size. However, you could make your application persist the toolbar information between sessions via QSettings:
http://doc.qt.nokia.com/latest/qsettings.html#details
http://doc.qt.nokia.com/latest/qsettings.html#restoring-the-state-of-a-gui-application
That would allow your users who wished to work in this style the option of setting it up like that, and let those who didn't like it save their preferred layout as well.

how to keep a nativewindow on top

I need to keep a NativeWindow I am creating on top of the main window of the application.
Currently I am using alwaysInFront = true, which is not limited to the windows in the application. I can successfully synchronize the minimize/restore/move/resize actions, so the top window behaves appropriately in those cases. Even though using this option has the drawback that if I alt-tab to other application the window goes on top of the other application.
Because of the above I am trying to get it to work without using the alwaysInFront. I have tried using orderInFrontOf and orderToFront, which gets it in place but when I click an area in the main window the top one becomes hidden i.e. air makes it the top one.
I have tried capturing activate/deactivate events but it only happens on the first click, so on the second click the top window becomes hidden again. I also tried making the top window active when the main one becomes active, but that causes the main one to loose focus and I can't click on anything.
Ps. I am doing this to improve the behavior of a HTMLOverlay I am using - see Flex Air HTMLLoader blank pop up window when flash content is loaded
Listening for Event.DEACTIVATE and calling event.preventDefault() should work. Not sure if that is what you have tried, but I have an app where that does the trick.
I ended up turning on/off the alwaysInFront option based on whether the main window or the top window were active i.e. if none where active I turned it off. This was additionally to what I mentioned in the question.
That way when the user switches to another application, the window doesn't go on top of the other apps. I still would prefer a solution where I don't have to use the alwaysInFront option, or even better an alternate solution to the flex loading flash in external sites issue I linked to above.
Ps. I will try to check with the owner of the HTMLOverlay to submit a patch (its an improvement, although its tied to an app that doesn't open extra windows when opening the overlay).
Update: I have committed the changes to the HTMLOverlay.
I'm trying to do something very similar. In an AIR application, I have one large full screen window which is essentially the "desktop". I always want this window to stay behind all other windows in my app. There are, however, some items on the "desktop" window that need to be clickable.
There appears to be no clean way to force a window to maintain its position in the window ordering.
What I've settled on so far, which isn't perfect, is to make all other windows in my app use the alwaysOnTop property but bind this to a global var (ugh) that I maintain to track the overall application level active/inactive state. This way, when I switch to another app, my windows don't float above the all other app windows - they correctly move behind as expected.
Then, I have a regular (alwaysOnTop=false) window that is fully transparent as an "overlay" to the desktop window on which I can place various interactive controls. This window is OK to come forward since it's transparent and my other windows are alwaysOnTop.
Finally, and crucially, I install three event listeners on the "desktop" window as follows:
protected function onApplicationComplete(event:Event):void
{
this.addEventListener(MouseEvent.MOUSE_DOWN, onClickHandler, true,1000,true);
this.addEventListener(MouseEvent.CLICK, onClickHandler, true,1000,true);
this.nativeWindow.addEventListener(Event.ACTIVATE, onActivateWindow,false,-1);
}
protected function onActivateWindow(event:Event):void
{
trace("sent via activate to back");
orderInBackOf(bigTransparentWindow);
}
protected function onClickHandler(event:MouseEvent):void
{
trace("sent via click to back");
orderInBackOf(bigTransparentWindow);
}
I'm not entirely happy with all this since there is still some occasionally noticeable flicker of objects in the overlay window - it appears that the "Desktop" window gets ordered in front of it, an update of some sort happens, and then it gets forced behind again.
Any better solutions welcome!

Air application created with Flex - How do I create a fly-out window to the left/right

I have an Air application with a main window. I would like to have a new window fly out from the side of the main window when the user clicks on a button in the main window. The window that appears needs to display information based on value passed from the main form. How can I achieve this with Flex Builder 3?
Target platform: any version of Flash/Flex/Air.
You'll probably want to use view states. Check out the Flex in one Week video tutorial on "Creating View States":
http://www.adobe.com/devnet/flex/videotraining/
What you want to do is what tweenMax was made for. it's a .swc that you add into your project. It will allow you to use the tweenLite (or tweenMax) command.
import com.greensock.*;
TweenLite.to(mc, 1, {x:65, y:117});
So you would say if your stage was 500 px wide and you want the box to come in from the right. Add the child at maybe 505, and then tween.to whatever x value you want. Yep. it's that easy. And the other parameters are for duration and easing and even alpha so you have control over that too. They even have a swf in the website so you an play with it and practice. http://www.greensock.com/tweenmax/

Resources