6

I would like to activate my Swing application programatically. I mean that I would like to write code that cause the JFrame to be visible and focused (the window header should be highlighted). I tried to use requestFocus(). It works only if application has at least 2 windows A and B: A is hidden, B is visible. Now if I call A.requestFocus() it becomes active as I want. It does not happen if application has only one window or if both windows are invisible.

I found 2 workarounds.

  1. use fake transparent undecorated frame that is always on top. This fake window will play role of window B. I did not try to implement it but it seems that it should work.
  2. call A.setAlwaysOnTop(true). This brings window A on top of other windows. But it is not in focus yet. Use java.awt.Robot (mouseMove, mousePress, mouseRelease) to make a click on the header of window A. Now call A.setAlwaysOnTop(false) and return mouse pointer back to its previous position. I implemented the code and it works but it looks like an ugly workaround.

Is there a "right" solution?

AlexR
  • 114,158
  • 16
  • 130
  • 208

4 Answers4

6
frame.setState(Frame.NORMAL); // restores minimized windows
frame.toFront(); // brings to front without needing to setAlwaysOnTop
frame.requestFocus();

for everything you could want to know in excruciating detail, see this page: http://www.developer.com/java/other/article.php/3502181/Window-Focus-and-State-in-Java.htm

Brad Mace
  • 27,194
  • 17
  • 102
  • 148
  • Use `requestFocusInWindow` instead of `requestFocus`, see http://download.oracle.com/javase/tutorial/uiswing/misc/focus.html. – Geoffrey Zheng Oct 26 '10 at 03:01
  • @Geoffrey - no... that's for focusing components *inside* of windows, not the windows themselves. May be a good link for him to check out if he's still having problems though. – Brad Mace Oct 26 '10 at 03:09
  • thanks for the correction, though I think it's more common to focus on a inside component that takes user input instead of the frame itself, as that allows user to start typing immediately if the frame's default component is editable text. – Geoffrey Zheng Oct 26 '10 at 04:03
2

I've found out this solvation of the problem:

//frame - JFrame
frame.setExtendedState(JFrame.ICONIFIED);
frame.setExtendedState(JFrame.NORMAL);
frame.toFront();
frame.requestFocus();

On my configuration (win 7, java 12) - it works alright and stably

1

This should do it:

frame.setSelected(true);

and you probably want it inside a try/catch block...

If that doesn't work on the OS you're using, there are two more possibilities:

frame.setAlwaysOnTop(true);
frame.setAlwaysOnTop(false);

and

frame.setVisible(true);
frame.setVisible(true); // Yes you need this second one
Michael Goldshteyn
  • 71,784
  • 24
  • 131
  • 181
  • As far as I can tell there is no `Frame.setSelected` method – Brad Mace Oct 23 '10 at 18:51
  • I tried both methods and unfortunately both do not work for me. setAlwaysOnTop brings window on top but does not make it active. This is what I already knew. toFront() cause the corresponding button on the toolbar to blink but window is not shown. So, it seems that my trick with simulation of mouse click on the window header using Robot is not so bad... – AlexR Oct 23 '10 at 22:48
1

I was in the same boat - none of the above worked.

"MY" solution was follows:

thisFrame.getWindowListeners()[0].windowActivated(
     new WindowEvent(
              thisFrame,
              WindowEvent.WINDOW_ACTIVATED
     )
);
schedulesTable.requestFocus();

thisFrame = the window to get activated

schedulesTable = my component in the window I wanted to get focus for
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • Thanks. Although I asked this question many years ago and that project is irrelevant now I will probably try your solution. – AlexR Mar 10 '17 at 06:00