I'm searching for a solution in order to keep a JFrame always on top and with always I really mean always.
setAlwaysOnTop( true );
This won't work when I'm starting a game in fullscreen mode. I know you normally don't want your windows to stay on top but in this case it's required.
This can't be done.
For example, the Windows Task Manager, even when set to Always on Top will get covered up by full-screen applications.
This is due to the fact that full-screen applications typically use a different graphics context and can't be overlayed.
Start another process to check if the window is on top,if not, set it on top.
This is a sample code that should be helpful
public class AllWaysOnTop extends JFrame implements WindowListener {
AllWaysOnTop() {
// Code to setup your frame
addWindowListener(this);
// Code to show your frame
}
// The window event handlers. We use WindowDeactivated to
// try and keep the splash screen on top. Usually only keeps
// the splash screen on top of our own java windows.
public void windowOpened(WindowEvent event){};
public void windowActivated(WindowEvent event){};
public void windowDeactivated(WindowEvent event){
toFront();
}
public void windowIconified(WindowEvent event){};
public void windowDeiconified(WindowEvent event){};
public void windowClosed(WindowEvent event){};
public void windowClosing(WindowEvent event) {};
}
Reference
This forum post
This sounds like the kind of question that Raymond Chen always has to answer over at Link. How can you really really forever and for true keep a window in the foreground? You can't. Because what happens if somebody ELSE's window uses the same trick to keep itself always always and forever in the foreground? Which one wins?
If you mean fullscreen as in DirectX/OpenGL/whatever, I'm not sure you can (or should) really pull it off. Most operating systems disable their native windowing during full screen to improve rendering performance. Swing works via the native windowing toolkit.
You could write something that uses a timer and in short intervals (e.g., 200ms) instructs your window to go to the top. Depending on your operating system this would be exactly what you need, or a horrible cause of performance trouble or flickering.
I'm not sure but i would bet that the Fullscreen window also has Always On Top set to true, and in that case you have stumbled into the realm of undefined behavior. In general when two windows are set to always on top there is no guarantee about ordering. I think in general though the order is just dependent on the order in which they were set to always on top. So in that case i would just wait until the app has gone fullscreen to set it to always on top and see if that works.
In other cases ive seen people start threads and then occasionally reset the fram to always on top.
All these solutions are ugly, so just use the one that lets you sleep at night.
I know this post is old, but I encountered this problem and I found a satisfying solution.
My program has some notifications that I wish to be always on top, but when a movie entered full-screen, they disappeared. Fortunate, my program updates these notifications every 5 seconds, and if I call setVisible(true) on these JWindows, at each update, they regain the top position, if they have lost it.
I was looking to do the same thing as OP, have my app running in the foreground while my game ran. It doesn't work in fullscreen but if you put the game into windowed mode and adjust the window settings to fit your tv it works. I only needed the frame.setAlwaysOnTop to make it work.
Related
i was wondering if it is possible to pass an MouseEvent, which occurs on a specific Stage to pass through the window of another program/application which to be fired there.
To be more specific, i want to program a HUD-like program for informational purposes, which should not interfere with the normal desktop usage (such as operating scrollbars/buttons which are underneath the "HUD").
One approach to accomplish such behaviour could be achieved using the Robot class in combination with an MouseListener.
Example:
scene.setOnMouseClicked(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event) {
stage.hide();
robot.mousePress(InputEvent.BUTTON1_MASK)
stage.show();
}
});
That should work (not yet tried), but feels kinda like a workaround, also this attempt should make problems if one tries to handle drag & drop. Are there any other possibilities to pass any kind of MouseEvents to other windows? Is it possible to make a Stage mouse transparent such as it is possible for Nodes ?
I am trying to find a method that can close the active JFrame.
I am unable to use frame.dispose();, as I am declaring the action listener in a toolbar class and the frames I want to close are not static and are declared at runtime.
I have tried using:
java.awt.Window win[] = java.awt.Window.getWindows();
for(int i=0;i<win.length;i++){
win[i].dispose();
}
and whilst this does work, in certain circumstances it will close more than one window even though only 1 window appears to be open, so frames will flash open and closed many times depending on what actions the user has made.
For me to fully recreate my problem would involve posting a significant amount of code which would not be in line with MCVE principles.
I am hoping someone will know of a more simple and reliable way of closing the active frame in the mould of acitveframe.dispose(); - which I now is not a real solution!!
What happens if you try to get the Window ancestor of the source of the action event? i.e.,
#Override
public void actionPerformed(ActionEvent actionEvent) {
Component comp = (Component) actionEvent.getSource();
Window win = SwingUtilities.getWindowAncestor(comp);
win.dispose();
}
This won't work if the source is not a Component or if it is not contained within the top level Window of interest.
Regarding:
For me to fully recreate my problem would involve posting a significant amount of code which would not be in line with MCVE principles.
I'll bet with a bit of effort you could create and post something that comes close.
I am hoping someone will know of a more simple and reliable way of closing the active frame
In your loop you can add:
if (window.isActive())
// do something
Or maybe a simpler approach is:
Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
Also, assuming your active window is a JFrame, instead of using window.dispose(), I have used code like:
WindowEvent windowClosing = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
frame.dispatchEvent(windowClosing);
this will simulate the user clicking on the "Close" button which means that any WindowListener you added to the frame will also be executed. See Closing an Appplication for more information and ideas.
When you are declaring your JFrames, declre them as final if you cannot use static :
final JFrame f = new JFrame();
It would solve the problem.
So my question, as stated (sort of) in the title, is about the behaviour in some respects of the Javafx (namely 2.2) Popup. Most of the time, you get a popup, and you give it a window to act as it's parent, you give it some scene, and it tends to act relatively independently.
This is all fine, however, in my case, I needed a popup that would anchor itself to a particular stage (window), at a particular location, when an event happened. That popup would then, in turn, disappear when the window disappeared (minimize, off screen, whatever), moved when it would, and in all essence and functionality, be a physical extension of the window, just with a custom shape.
Now of course, there are a lot of nuances with that, and everything for the most part, works great. The only thing I can't seem to figure out is that normally in a platform like Windows 7 64 bit, say. You open two programs, alright. Then if the programs are overlapping a little bit, whichever has focus gets to have the entire program displayed, whereas the other one gives the impression of being 'behind' the other window. (Whether or not windows actually renders application graphics 'behind' a window when another has focus on the same spot, I'm not sure.). Normally, javafx also supports this functionality just fine. But for some reason, The Popup class in javafx (see docs here) doesn't do that. It's always on top of whatever it's displayed with, without exception. For the point of completeness, here's my pretty straightforward popup code (at least the part pertaining to showing it and it's properties):
Popup myPop = new Popup();
//************************Popup Property Setter**************************
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
myPop.setWidth(width);
myPop.setHeight(initialHeight);
myPop.setAutoHide(false);
myPop.setAutoFix(false);
myPop.setHideOnEscape(false);
myPop.setX(xLocation);
myPop.setY(yLocation);
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//**********************end of Popup Properties**************************
myPop.getContent().add(main_anchor);
myPop.show(FileChooserWindow.get_stage());
main anchor has some various components i include inside of the 'myPop' popup, and FileChooserWindow is a non-null parent window that will be open at the time of this method calling without exception.
Here is a screenshot as well of the behaviour I'm referring to. Notice the highlighted text in the pdf, that is where my cursor currently has focus. Also, the window that the popup is anchored to can be seen in the back of the pdf poking out from the left.
Any help you guys can give would be much appreciated. I really hope I don't have to check for active processes and their location relative to the popup, that's getting dangerously close to my knowledge border, and sounds like a total PITA.
So, after toying with this for a few more days, I have a rough workaround, although it is a hack in the full meaning of the term.
Although the popup behaviour is still mystifying me, I can simulate a fix in this behaviour by adding a changeListener to the stage to which it is attached (since I didn't want the popup to close if it's parent window had focus, only if anything BUT the popup and it's parent got focus).
See code as follows:
FileChooserWindow.get_stage().focusedProperty().addListener(new ChangeListener<Boolean>(){
#Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean oldValue, Boolean newValue) {
if (!newValue){
if(AutogenPopup.popupReturner().focusedProperty().get()){
AutogenPopup.popupReturner().hide();
}
}else{
if(FileChooserController.refreshAutoPopup && FileChooserController.autoGen_flag){
AutogenPopup.popupReturner().show(FileChooserWindow.get_stage());
}
}
}
});
never mind some of those flags that I'm checking against, they are simply some internal tools to make sure that the popup only appears when the program is in the proper state.
Now, one interesting thing to note. The AutogenPopup.popupReturner().focusedProperty().get()
Seemed to be returning true when the popup's parent window LOST focus. Which is quite counter-intuitive to me, and in my opinion, is even a touch buggy. Now, this does not simulate the behaviour of a modern operating system where a window can slide in and out of focus incrementally, since the popup will just completely disappear upon it's parent window losing focus. But seeing as how my popup just displays additional text entry on the side of the main window, this is an acceptable compromise until I think of a better solution. (Perhaps the better solution is not to use a popup at all, and instead skin a window to act in a popup-y fashion).
Anyway, I hope this helps someone, maybe eventually there will be a more fine-grained way to control this popup functionality.
I know this is sort of a vague question, but I will try to make it as clear as possible. When my Java app launches for the first time, it does some checking to see if files and directories exist and checks for an internet connection.
The app then allows the user to move on to the dashboard, which requires loading and adding many Swing components to the Background Panel. This takes time.
I was wondering how I could make it so that during the loading process at the start, the app loads all of the Swing components Images etc. so that they appear instantly when the user executes the command to do so.
I can load all of the components like this:
JButton = new JButton("blah");
but I'm not sure that's enough to make the components appear instantly, wouldn't adding several image filled Swing components at the same time still lag the UI thread, even if it was already "loaded" as seen above?
Thanks!
on the components use
setVisible(false)
for example
public class myParentPanel extends JPanel{
public myParentPanel{
//add all the child components
//Do what ever takes along time
setVisible(false); //this then makes in invisible but still
//allows all the set up code to run
}
public void showParent(){
setVisible(true);
invalidate();
}
}
and then create a method to make them visible when required. Hence all your setting in the constructors ca be called then when you call your method say:
drawWindow()
it then only has to call setVisible(true) and invalidate the screen to call their painting methods :).
An advancement on this would be to *run your setups i.e your checking and loading the panels methods on a separate threads*so you don't have to wait for a sequential loading. So on your loading you may to use an anonymous class
SwingUtilities.invokeLater(new Runnable(){ public void run(){
//do my display set up
}});
I've been running up against a problem with Java Swing + my Wacom Graphire tablet for a few years in several Java applications and have now encountered it in my own.
I use a pen tablet to get around wrist issues while clicking a mouse, and it works fine under Windows except when I'm using Java applications. In Java applications, the single-click of the pen doesn't work correctly. (Usually the problem only occurs with file-selection dialog boxes or tree controls.) The pen tablet also comes with a wireless mouse that works with the same tablet, and its single-click does work correctly.
I don't know whether the problem is in the WACOM driver or in the Java Swing runtime for Windows or both. Has anyone encountered this before? I'd like to file a bug report with WACOM but I have no idea what to tell them.
I have been able to reproduce this in my own application that has a JEditorPane with an HTML document that I've added a HyperlinkListener to. I get HyperlinkEvent.ACTIVATED events on every single click with the mouse, but I do NOT get HyperlinkEvent.ACTIVATED events on every single click with the pen.
One big difference between a pen and a mouse is that when you click a button on a mouse, it's really easy to cause the button-click without mouse movement. On the pen tablet it is very hard to do this, and that seems to correlate with the lack of HyperlinkEvent.ACTIVATED events -- if I am very careful not to move the pen position when I tap the tablet, I think I can get ACTIVATED events.
Any suggestions for things to try so I can give WACOM some good information on this bug? It's really frustrating to not be able to use my pen with Java apps, especially since the pen works fine with "regular" Windows (non-Java) applications.
Normally I wouldn't ask this question here but I'd like to find out from a programmer's standpoint what might be going on so I can file a good bug report.
What you should do is add a mouseListener and see when it registers a mouseClicked(), mousePressed(), mouseReleased() event. I'm not sure if the swing reads the tablet pen as a mouse though. However, it should give you some insight into what's actually going on.
I tried dr.manhattan's suggestion and it works like a charm. I get mousePressed/mouseReleased events correctly; mouseClicked events happen always with the pen tablet mouse, but mouseClicked events do not happen with the pen unless I manage to keep the pen very still. Even a 1-pixel movement is enough to make it fail. I guess I should blame Java for this one: there's no way to specify a "click radius" for acceptible movement.
package com.example.bugs;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
public class WacomMouseClickBug {
public static void main(String[] args) {
JFrame jframe = new JFrame();
jframe.addMouseListener(new MouseListener(){
#Override public void mouseClicked(MouseEvent event) {
System.out.println("mouseClicked: "+event);
}
#Override public void mouseEntered(MouseEvent event) {}
#Override public void mouseExited(MouseEvent event) {}
#Override public void mousePressed(MouseEvent event) {
System.out.println("mousePressed: "+event);
}
#Override public void mouseReleased(MouseEvent event) {
System.out.println("mouseReleased: "+event);
}
});
jframe.setPreferredSize(new Dimension(400,400));
jframe.pack();
jframe.setLocationRelativeTo(null);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
}
}
I think you already got the answer yourself: Moving the pen results in some other event than a simple click, perhaps maybe a Drag and drop like event.
I'm not sure whether it's a Java/Swing or a Wacom problem, it could be that the tablet doesn't register the clicks as such but as drag events, or it could be that swing interprets the events incorrectly.
I reported this bug many years ago to Sun. It still is not fixed. Any decent ui framework will allow some movement between a press and release to generate a click event. A maximum movement of 1 pixel on a high dpi display is just ridiculous. It is not only an issue with wacom tablets, ie older people also have difficulties to keep the mouse still when clicking.