There are numerous caveats in the javadoc for the toFront() method which may be causing your problem.
But I'll take a guess anyway, when "only the tab in the taskbar flashes", has the application been minimized? If so the following line from the javadoc may apply:
"If this Window is visible, brings this Window to the front and may make it the focused Window."
Windows has the facility to prevent windows from stealing focus; instead it flashes the taskbar icon. In XP it's on by default (the only place I've seen to change it is using TweakUI, but there is a registry setting somewhere). In Vista they may have changed the default and/or exposed it as a user accessible setting with the out-of-the-box UI.
Preventing windows from forcing themselves to the front and taking focus is a feature since Windows 2K (and I, for one, am thankful for it).
That said, I have a little Java app I use to remind me to record my activities while working, and it makes itself the active window every 30 minutes (configurable, of course). It always works consistently under Windows XP and never flashes the title bar window. It uses the following code, called in the UI thread as a result of a timer event firing:
(the first line restores if minimized... actually it would restore it if maximized too, but I never have it so).
While I usually have this app minimized, quite often it's simply behind my text editor. And, like I said, it always works.
I do have an idea on what your problem could be - perhaps you have a race condition with the setVisible() call. toFront() may not be valid unless the window is actually displayed when it is called; I have had this problem with requestFocus() before. You may need to put the toFront() call in a UI listener on a window activated event.
2014-09-07: At some point in time the above code stopped working, perhaps at Java 6 or 7. After some investigation and experimentation I had to update the code to override the window's toFront method do this (in conjunction with modified code from what is above):
setVisible(true);
toFront();
requestFocus();
repaint();
...
public @Override void toFront() {
int sta = super.getExtendedState() & ~JFrame.ICONIFIED & JFrame.NORMAL;
super.setExtendedState(sta);
super.setAlwaysOnTop(true);
super.toFront();
super.requestFocus();
super.setAlwaysOnTop(false);
}
As of Java 8_20, this code seems to be working fine.
I had the same problem with bringing a JFrame to the front under Ubuntu (Java 1.6.0_10). And the only way I could resolve it is by providing a WindowListener. Specifically, I had to set my JFrame to always stay on top whenever toFront() is invoked, and provide windowDeactivated event handler to setAlwaysOnTop(false).
So, here is the code that could be placed into a base JFrame, which is used to derive all application frames.
@Override
public void setVisible(final boolean visible) {
// make sure that frame is marked as not disposed if it is asked to be visible
if (visible) {
setDisposed(false);
}
// let's handle visibility...
if (!visible || !isVisible()) { // have to check this condition simply because super.setVisible(true) invokes toFront if frame was already visible
super.setVisible(visible);
}
// ...and bring frame to the front.. in a strange and weird way
if (visible) {
toFront();
}
}
@Override
public void toFront() {
super.setVisible(true);
int state = super.getExtendedState();
state &= ~JFrame.ICONIFIED;
super.setExtendedState(state);
super.setAlwaysOnTop(true);
super.toFront();
super.requestFocus();
super.setAlwaysOnTop(false);
}
Whenever your frame should be displayed or brought to front call frame.setVisible(true).
Since I moved to Ubuntu 9.04 there seems to be no need in having a WindowListener for invoking super.setAlwaysOnTop(false) -- as can be observed; this code was moved to the methods toFront() and setVisible().
Please note that method setVisible() should always be invoked on EDT.
The rules governing what happens when you .toFront() a JFrame are the same in windows and in linux :
-> if a window of the existing application is currently the focused window, then focus swaps to the requested window
-> if not, the window merely flashes in the taskbar
BUT :
-> new windows automatically get focus
So let's exploit this ! You want to bring a window to the front, how to do it ? Well :
Create an empty non-purpose window
Show it
Wait for it to show up on screen (setVisible does that)
When shown, request focus for the window you actually want to bring the focus to
hide the empty window, destroy it
Or, in java code :
// unminimize if necessary
this.setExtendedState(this.getExtendedState() & ~JFrame.ICONIFIED);
// don't blame me, blame my upbringing
// or better yet, blame java !
final JFrame newFrame = new JFrame();
newFrame.add(new JLabel("boembabies, is this in front ?"));
newFrame.pack();
newFrame.setVisible(true);
newFrame.toFront();
this.toFront();
this.requestFocus();
// I'm not 100% positive invokeLater is necessary, but it seems to be on
// WinXP. I'd be lying if I said I understand why
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
newFrame.setVisible(false);
}
});
Hj, all methods of yours are not working for me, in Fedora KDE 14. I have a dirty way to do bring a window to front, while we're waiting for Oracle to fix this issue.
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
public class FrameMain extends javax.swing.JFrame {
//...
private final javax.swing.JFrame mainFrame = this;
private void toggleVisible() {
setVisible(!isVisible());
if (isVisible()) {
toFront();
requestFocus();
setAlwaysOnTop(true);
try {
//remember the last location of mouse
final Point oldMouseLocation = MouseInfo.getPointerInfo().getLocation();
//simulate a mouse click on title bar of window
Robot robot = new Robot();
robot.mouseMove(mainFrame.getX() + 100, mainFrame.getY() + 5);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
//move mouse to old location
robot.mouseMove((int) oldMouseLocation.getX(), (int) oldMouseLocation.getY());
} catch (Exception ex) {
//just ignore exception, or you can handle it as you want
} finally {
setAlwaysOnTop(false);
}
}
}
//...
}
I tested your answers and only Stefan Reich's one worked for me. Although I couldn't manage to restore the window to its previous state (maximized/normal). I found this mutation better:
Ran into a problem with the iconified/restore approach on Windows when the application has multiple JFrames. In this case, I found that hiding the other JFrames, then forcing the window to the front, then unhiding the JFrames did the trick.
private static void bringFrameToTop(Frame topFrame) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
List<Frame> framesToShow = new ArrayList<>();
for(Frame f : Frame.getFrames()) {
if (f != topFrame && f.isShowing()) {
framesToShow.add(f);
f.setVisible(false);
}
}
// Force our dialog to the front
int origState = topFrame.getExtendedState();
topFrame.setExtendedState(JFrame.ICONIFIED);
topFrame.setExtendedState(origState);
// these don't appear to help anything
// topFrame.toFront();
// topFrame.repaint();
for(Frame f : framesToShow) {
f.setVisible(true);
}
topFrame.toFront();
}
});
}