What's the main difference between the method windowActivated (implemented from WindowListener) and windowGainedFocus (implemented from WindowFocusListener)?
The Java documentaion says:
windowGainedFocus:
Invoked when the Window is set to be the focused Window, which means that the Window, or one of its subcomponents, will receive keyboard events.
windowActivated:
Invoked when the Window is set to be the active Window. Only a Frame or a Dialog can be the active Window. The native windowing system may denote the active Window or its children with special decorations, such as a highlighted title bar. The active Window is always either the focused Window, or the first Frame or Dialog that is an owner of the focused Window.
But what's the difference? Or is it just as it says, that a focused window is a type of activated window?
Thanks in advance!
From How to Write Window Listeners which reflects the quote in your question aswell:
windowActivated(WindowEvent) and windowDeactivated(WindowEvent):
Called just after the listened-to window is activated or deactivated,
respectively. These methods are not sent to windows that are not
frames or dialogs. For this reason, the windowGainedFocus and
windowLostFocus methods to determine when a window gains or loses the
focus are preferred.
So windowActivated is only executed when the window is a frame or dialog, while the windowGainedFocus is for all types.
The focused window is the one that receives keyboard input.
An active window is typically the document window that the user is manipulating.
An active window is generally distinguished visually, for example, with a different title bar.
In macOS, the focused window is called the key window and the active window (there can be only one) is called the main window.
The distinction is subtle because they are almost always the same window.
An example where they differ would be a floating palette that contains a text field. The palette would need to be the focused window to accept keyboard input, but the document window is the active window where the changes are actually made and it should be distinguished from other (inactive) document windows.
Although Java distinguishes active and focused windows in its API, the implementation links them together so that some combinations (like the above example) are not possible, or at least difficult to arrange. For example, if you click on a focusable Java window, it becomes both the focused window and the active window.
Related
I am developing a Java Swing-based application with different perspectives. For the "main menu" perspective I do not want the window (JFrame) to be decorated, while in other perspective I do want the window to be decorated. In other words, I need want to change the decoration attribute dynamically.
I have tried to use setUndecorated(false) and setUndecorated(true), but I seems I can only set this once, before actually showing the window.
Is there a way to achieve this?
From the javadoc:
Disables or enables decorations for this frame. This method can only be called while the frame is not displayable.
Therefore, once the JFrame is packed and/or displayed, you can no longer change that value. If you want to change the undecorated state of a JFrame you will need to dispose() it first, then change the state and eventually make it visible again.
After all, I had to take a different approach.
The former solution did work, as I stated in my last comment.
However, it was showing the default LAF window decoration, while I was using a different LAF.
So the result was graphically inconsistent with the rest of the LAF. Finally, I came with the right solution, I used setUndecorate(true) for my frame. Then, when I had to change my perspective to one using decorations I simply had to use the following code
contentPane.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
And when I had to revert to the non decorate perspective, I use
contentPane.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
This approach didn't need to dispose the window and show it again (which actually produced a brief but still visible hide/show of the window)
This is most likely an obvious question, but I was wondering how I can keep a program behind all other windows (except the desktop)?
In a way, I am trying to achieve the opposite of keeping a window in the front.
Here's an example:
Window 1
Window 2
Random Window
My App
Desktop
However, I need it so that it will always stay against the desktop, so you cannot interact with it unless you're looking at the desktop itself.
public void toBack()here
If this Window is visible, sends this Window to the back and may cause it to lose focus or activation if it is the focused or active Window.
Places this Window at the bottom of the stacking order and shows it behind any other Windows in this VM. No action will take place is this Window is not visible. Some platforms do not allow Windows which are owned by other Windows to appear below their owners. Every attempt will be made to move this Window as low as possible in the stacking order; however, developers should not assume that this method will move this Window below all other windows in every situation.
4 Years late, but if you need the window to always stay in the back, even when the user clicks on it, you can use:
JFrame frame = new JFrame("");
frame.setFocusableWindowState(false);
frame.toBack();
setFocusableWindowState(false) prevents the activation of the window when clicked.
I have an application that uses the JOptionPane.show* methods to inform the
user about various conditions before displaying the applications main window.
On a multi screen setup these always show on the first screen. This is usually only
a minor annoyance, but becomes a problem when the 0 screen is off or disconnected.
Normal windows can be placed correctly using the GraphicsConfiguration obtained
via MouseInfo, but I can't find a way to pass that to JOptionPane. I can
not either use the main window to anchor the dialogs, because there is no main
window at that stage of the application startup. Among the possible dialogs is
a warning about obsolete java versions, so displaying the main window before the
errors is not option since the user's java runtime may not even be capable of
displaying the main window.
Is there a way to specify the target screen without reimplementing a major part
of JOptionPane?
You can create a JDialog out of a JOptionPane, and then display the dialog any location that you desire.
As per the JOptoinPane API:
JOptionPane pane = new JOptionPane(arguments);
pane.set.Xxxx(...); // Configure
JDialog dialog = pane.createDialog(parentComponent, title);
// here set the dialog's location
dialog.setVisible(true);
Edit: Alternatively, you could simply create your own JDialog window de novo as per Andrew's great comment (that now no longer exists?).
I am developing a Java Swing-based application with different perspectives. For the "main menu" perspective I do not want the window (JFrame) to be decorated, while in other perspective I do want the window to be decorated. In other words, I need want to change the decoration attribute dynamically.
I have tried to use setUndecorated(false) and setUndecorated(true), but I seems I can only set this once, before actually showing the window.
Is there a way to achieve this?
From the javadoc:
Disables or enables decorations for this frame. This method can only be called while the frame is not displayable.
Therefore, once the JFrame is packed and/or displayed, you can no longer change that value. If you want to change the undecorated state of a JFrame you will need to dispose() it first, then change the state and eventually make it visible again.
After all, I had to take a different approach.
The former solution did work, as I stated in my last comment.
However, it was showing the default LAF window decoration, while I was using a different LAF.
So the result was graphically inconsistent with the rest of the LAF. Finally, I came with the right solution, I used setUndecorate(true) for my frame. Then, when I had to change my perspective to one using decorations I simply had to use the following code
contentPane.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
And when I had to revert to the non decorate perspective, I use
contentPane.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
This approach didn't need to dispose the window and show it again (which actually produced a brief but still visible hide/show of the window)
I have a modeless dialog box being generated which prompts users to open a new window. The box can be opened in two ways, either directly from the file menu for the frame I'm writing or indirectly via the framework my panel is plugging into.
When I make the call directly via the file menu the dialog box comes up with focus exactly as I want. But when I have the framework indirectly open the dialog box it does not have focus as it should.
There doesn't seem to be a difference between the two methods of opening the dialog, in both cases a load function is called and it's not until 5 method calls later the dialog box is opened. In both cases the frame which generates the dialog box is realized at the time the box is generated. I've tried calling requestFocus after making the dialog box visible but it doesn't seem to do anything.
Any suggestion why the dialog box wouldn't have focus, or how I can give it focus as a separate window from the window that usually has focus?
in some cases is hard to set Focus to the expected top-level container as are demonstrated here , but for excelent workaround would be better look at camickr's Dialog Focus
When you create the dialog, try setting the main GUI as parent of the dialog.
In the first case, when you click from menu, it automatically sets the main GUI as the parent of the dialog, but it doesnt in the second case.
So make sure when you create the dialog, you are setting the main GUI/ window as parent always.
It should help most times.