How to focus JDialog programmatically? - java

I have read some of those similar threads here but they did not help me.
I have my JDialog that is undecorated and initially is unfocusable:
super(connectionsTree.getMainFrame(), "", false);
super.setUndecorated(true);
super.setFocusableWindowState(false);
super.setFocusable(false);
super.getContentPane().add(scrollPane);
super.pack();
Now whenever this dialog is visible and user tpes Space button I must make that JDialog focused so that it receives key events.
I do it like so :
if (keyCode == 32) {
tooltip().setFocusable(true);
tooltip().setFocusableWindowState(true);
tooltip().requestFocusInWindow();
}
This code makes my JDialog focusable but JDialog is not focused and key events are not grasped by it.
tooltip() method only returns instance of my JDialog.
How to make my JDialog receive focus programmatically?
Thank you!

According to documentation of requestFocusInWindow() focus to Component will be granted only if top level parent component is focus owner. So this will not work if your main window has no focus on it. You should use Component#requestFocus() instead.
From Component#requestFocus() description
Requests that this Component get the input focus, and that this Component's top-level ancestor become the focused Window.

Related

How to detect if user clicks on window title bar or any other part of window border in Java

I have implemented a pop-up numeric keypad using the Swing Popup class. I have a button associated with a JTextField that opens the numeric keypad when the user clicks on it, and then when/if the JTextField loses focus the Popup closes. It generally works well, except that occasionally I get artifacts that are "left over" from a Popup after it has been hidden. Sometimes the artifact is an image of the Components that were shown in the Popup, but more often it is a "black hole" of sorts that obscures anything else displayed in the same area of the screen in which the Popup had been, which can only be remedied by shutting down the application and the JVM.
The problem is difficult to reproduce, but it seems to manifest when the user manipulates the base Window while the Popup is open, such as by moving or resizing it. My thought is to simply hide the Popup when anything like that happens, which I can do with a combination of a WindowListener and a ComponentListener. However, I'd like to take it one step further and hide the Popup as soon as the user so much as clicks on the window title bar or another portion of its frame, even before they move, resize or iconify it. JComboBox popups in fact work this way. However, I have been unable to find any kind of mechanism by which I can be notified that a user has clicked on the window title bar. I've looked at the JComboBox and related code and can't figure out from that how it's working this magic, either. Is there any other kind of listener I could use to get this kind of notification?
I have implemented a pop-up numeric keypad using the Swing Popup class.
Well post your code demonstrating the implementation and problem when you post a question.
I don't know exactly what you are doing but you might be able to use a JPopupMenu. This will close when you click on the frame title bar with no FocusListener or any additional logic.
will be deleted, just code for testing,
private boolean _myWindowFocusLost = false;
.
_xxXxx.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {//Invoked when a component gains the keyboard focus.
if (e.getOppositeComponent() != null) {
if (e.getOppositeComponent() instanceof JComponent) {
JComponent opposite = (JComponent) e.getOppositeComponent();
if ((opposite.getTopLevelAncestor() != _myPopupWindow) && (!_myWindowFocusLost)) {
_myWindowFocusLost = false;
}
}
}
}
});

Problems with the modality of a JDialog (mouse events for main window both fired and buffered)

I made a JDialog and the modality works presumably fine
dialog.setModalityType(JDialog.ModalityType.APPLICATION_MODAL);
dialog.setVisible(true);
But then my problem is:
I´m throwing Jdialog after a jcombobox.setSelection() and I need to click twice in Accept button in order to hide the dialog, because dropdown popup is consuming the first click for closing himself. I fixed it by manually calling jcombobox.hidePopup() before calling the dialog, but I cannot understand if the later is modal, why the mouse events trigger things outside the window?`
My Main window buffers somehow the mouse events, so for those mouse events which are not activated when the modal dialog is drawn (as happens with the previous point), it seems they get buffered and are applied after dialog closure. Is this an expected behavior?
Thank u!
replace jcombobox.hidePopup("doesn't make me sence") with ActionListener or ItemListener added to the JComboBox
add RequestFocusListener by #camickr for setting the FocusOwner correctly
for why reasons are there another MouseListeners, maybe in the case that fird any events to the JComponents that you can't to set Focus correctly

How can I make a Swing text area have the focus as soon as it is loaded?

I've created a simple Swing panel that, when loaded, takes up my application's entire window. It contains two JTextAreas and a handful of buttons. I want one of the text areas to have the focus when the panel loads, so that the user can immediately start typing instead of having to click on the text area first. How can I achieve this?
By default focus goes to the first component defined on the window.
If this is not the component you want to have focus then you need to request focus once the window is realized.
The Dialog Focus example shows a couple of ways to do this.
See here the Documentation which contains exactlly what you are searching for (I think):
A component can also be given the
focus programmatically, such as when
its containing frame or dialog-box is
made visible. This code snippet shows
how to give a particular component the
focus every time the window gains the
focus:
//Make textField get the focus whenever frame is activated.
frame.addWindowFocusListener(new WindowAdapter() {
public void windowGainedFocus(WindowEvent e) {
textField.requestFocusInWindow();
}
});
You just need to call requestFocus method of Jcomponent class,
public void requestFocus()
On the Component that you want to focus.
And pleas make sure that you call this method after setVisible is called for its parent component.
For example:-
You have a Jframe in which you added a JTextArea, so after calling you should call in following order:-
jframe.setVisible(true);
jarea.requestFocus();

Java: If a custom JDialog is hidden, is focus returned back to its parent?

I am creating a custom JDialog. I need to hide the JDialog (without removing it from memory) so that its parent can call a method on the JDialog (getResults()).
JDialog dialog = new JDialog(.....);
///Code WITHIN JDialog:
{
//JDialog opens and its actions are performed
this.setVisible(false); //Does this allow the parent to gain focus once more?
}
It depends: whether JDialog modaless is or not. And also if you extend JDialog then:
Yes.
If it will disable focusing other windows, it will release this constraint when the JDialog is hidden. If the JDialog is visible again, it will be impossible to focus the other windows again.

How to make a button deep in a nested Swing panel get the "keyboard focus"?

I have a swing frame that contains embedded panels that contain other panels, etc.
Deep down, there is a button. I want the button to get focus so that pressing the "enter" key would generate an actionPerformed event.
However, if I do myButton.requestFocus() or myButton.requestFocusInWindow() the whole window gets the focus, but nothing seems to happen in terms of keyboard.
I'm obviously missing something about the focus subsystem.
Update2: I explicitly added a KeyListener in addition to the ActionListener and now it works. This is really weird, since I thought that actionListener includes both key and mouse actions.
For the enter key to work you probably want to set the default button rather than the keyboard focus:
button.getRootPane().setDefaultButton(button);
If you really want the keyboard focus then your problem might be related to when you call requestFocus. Sometimes if it is called before a component is fully visible it can be ignored. To fix that you can delay the requestFocus call until after other events have been processed:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
button.requestFocus();
}
});
Sounds like requestFocus() is failing at some level. Try testing to see if any of the parent jPanels or other components can request focus, and work your way up to find out where the problem lies.
There is a way to programatically specify the functionality of the tab ( you know when you press tab and the next widget gets selected )
By default it follows the way the components were added.
Using this custom mechanism will let you select your nested button as the first which receive the actionperformed event.
Unfortunately I don't remember what the name for this "mechanism" is, but is something like traversal or focus traversal
First, don't use requestFocus() use requestFocusInWindow(). requestFocus has platform specific issues, while requestFocusInWindow is more consistent.
Your actual problem; the component (or one of its parents) is probably not visible, or has been render non-focusable.
I want the button to get focus so that
pressing the "enter" key would
generate an actionPerformed event.
The is LAF dependents. Enter works in Windows, but not the Metal LAF. Check out Enter Key and Button for more inforation.
The requestFocusInWindow() method only works if the Component is currently visible on the frame. There are no other tricks so we are just making random guesses about what your are doing wrong. If you need further help you need to post a SSCCE demonstrating the problem.
You can get the rootPane of the frame and update the inputMap and actionMap. See the below code.
InputMap map = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ok");
ActionMap actionMap = getRootPane().getActionMap();
actionMap.put("ok", enterAction);
Here enterAction is a AbstractAction object whose actionPerformed() will be called when user presses Enter.

Categories