我们有一个Java应用程序,当远程控制机制激活该应用程序中的某些内容时,需要将其置于前台。
为了实现这一点,我们已经在该类的被调用方法中实现了该方法,该方法表示实现后我们应用程序的框架(扩展为JFrame
):
setVisible(true);
toFront();
在Windows XP下,此功能在首次调用时有效,第二次仅任务栏上的选项卡闪烁时,框架不再位于最前面。Win2k也是如此。在Vista上似乎工作正常。
你有什么想法?
我们有一个Java应用程序,当远程控制机制激活该应用程序中的某些内容时,需要将其置于前台。
为了实现这一点,我们已经在该类的被调用方法中实现了该方法,该方法表示实现后我们应用程序的框架(扩展为JFrame
):
setVisible(true);
toFront();
在Windows XP下,此功能在首次调用时有效,第二次仅任务栏上的选项卡闪烁时,框架不再位于最前面。Win2k也是如此。在Vista上似乎工作正常。
你有什么想法?
toFront()
EDT invokeLater
。下面包含一个简单的答案,但这不是公认的答案。确实可以。完美。
Answers:
可能的解决方案是:
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
myFrame.toFront();
myFrame.repaint();
}
});
JFrame
在Ubuntu(Java 1.6.0_10)下将a 置于最前面时,我遇到了同样的问题。我唯一可以解决此问题的方法是提供一个WindowListener
。具体来说,我必须将自己设置JFrame
为始终toFront()
被调用,始终保持在最前面,并向提供windowDeactivated
事件处理程序setAlwaysOnTop(false)
。
因此,这是可以放置在base中的代码,该代码JFrame
用于派生所有应用程序框架。
@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);
}
每当您的相框应显示或进行呼叫时frame.setVisible(true)
。
自从我移至Ubuntu 9.04以来,似乎不需要WindowListener
进行调用super.setAlwaysOnTop(false)
。此代码已移至方法toFront()
和setVisible()
。
请注意,setVisible()
应始终在EDT上调用该方法。
.setAlwaysOnTop(true);
使用JWindow时,这是唯一对我有用的工具。
setAlwaysOnTop(true)
是让它在Windows 10下运行的唯一方法-谢谢!
Windows具有防止Windows窃取焦点的功能。而是闪烁任务栏图标。在XP中,默认情况下它处于打开状态(我看到的唯一更改它的地方是使用TweakUI,但是某处有一个注册表设置)。在Vista中,他们可能已经更改了默认设置和/或使用即用型UI将其公开为用户可访问的设置。
自Windows 2K以来,防止Windows强迫自己进入焦点并成为焦点是一项功能(我对此很感激)。
就是说,我有一个小Java应用程序,用于提醒我记录工作时的活动,它使自己每30分钟成为活动窗口(当然是可配置的)。它在Windows XP下始终能够始终如一地工作,并且不会闪烁标题栏窗口。它使用以下代码,由于计时器事件触发而在UI线程中调用了以下代码:
if(getState()!=Frame.NORMAL) { setState(Frame.NORMAL); }
toFront();
repaint();
(如果最小化,第一行将还原。实际上,如果最大化也将还原它,但我从来没有这样)。
虽然我通常将此应用程序最小化,但通常它只是在我的文本编辑器后面。而且,就像我说的那样,它始终有效。
我确实对您的问题可能有个想法-也许您通过setVisible()调用遇到了竞争状况。除非窗口实际在调用时显示,否则toFront()可能无效。我之前在requestFocus()中遇到过此问题。您可能需要在窗口激活的事件上将toFront()调用放入UI侦听器中。
2014-09-07:在某个时间点,上面的代码可能无法运行,也许是在Java 6或7上。经过一些调查和实验,我不得不更新代码以覆盖窗口的toFront
方法来执行此操作(结合修改后的代码)以上):
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);
}
从Java 8_20开始,此代码似乎运行良好。
super.setAlwaysOnTop(false);
是这样的,所以窗口并不总是在最上面,这是摆脱true
我们先前设置的将窗口置于最前面的必要的,对吗?我问是因为对于您的代码,就我而言,窗口始终始终位于顶部,这显然是我不希望的。在Windows 10上运行jre1.8.0_66
这是一种真正有效的方法(在Windows Vista上测试):D
frame.setExtendedState(JFrame.ICONIFIED);
frame.setExtendedState(fullscreen ? JFrame.MAXIMIZED_BOTH : JFrame.NORMAL);
fullscreen变量指示您是希望应用程序全屏运行还是在窗口中运行。
这不会使任务栏闪烁,而是将窗口可靠地移到前面。
j,在Fedora KDE 14中,您的所有方法都不对我有用。
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);
}
}
}
//...
}
而且,这在我的Fedora KDE 14中非常有效:-)
这个简单的方法在Windows 7中非常适合我:
private void BringToFront() {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if(jFrame != null) {
jFrame.toFront();
jFrame.repaint();
}
}
});
}
repaint()
是没有必要的,该invokeLater()
做的。谢谢。
我测试了您的答案,只有Stefan Reich的答案对我有用。尽管我无法将窗口还原到以前的状态(最大化/正常)。我发现这种突变更好:
view.setState(java.awt.Frame.ICONIFIED);
view.setState(java.awt.Frame.NORMAL);
这是setState
不是setExtendedState
。
我发现最简单的方法在各个平台之间没有不一致之处:
setVisible(false); setVisible(true);
在Windows和Linux中,当您对JFrame .toFront()进行控制时,所发生的事情的规则是相同的:
->如果现有应用程序的窗口当前是焦点窗口,则焦点交换到请求的窗口->如果不是,则该窗口仅在任务栏中闪烁
但是:
->新窗口自动获得焦点
因此,让我们利用这个!您想把窗户放到前面,该怎么做?好 :
或者,在Java代码中:
// 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);
}
});
为了避免窗口在隐藏后返回可见状态时失去焦点,需要做的是:
setExtendedState(JFrame.NORMAL);
像这样:
defaultItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showWindow();
setExtendedState(JFrame.NORMAL);
}
});