Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何把窗户放在前面?_Java_Windows_Swing_Awt - Fatal编程技术网

Java 如何把窗户放在前面?

Java 如何把窗户放在前面?,java,windows,swing,awt,Java,Windows,Swing,Awt,我们有一个Java应用程序,当遥控机制激活应用程序中的某些内容时,需要将其置于前台 为了实现这一点,我们在类的被调用方法中实现了以下实现,该类表示我们应用程序的框架(扩展了JFrame): setVisible(true); toFront(); 在Windows XP下,它在第一次调用时工作,第二次只有任务栏中的选项卡闪烁,框架不再出现在前面。Win2k也是如此。在Vista上,它似乎运行良好 您有什么想法吗?javadoc中有许多关于toFront()方法的内容,这些内容可能会导致您的问题

我们有一个Java应用程序,当遥控机制激活应用程序中的某些内容时,需要将其置于前台

为了实现这一点,我们在类的被调用方法中实现了以下实现,该类表示我们应用程序的框架(扩展了
JFrame
):

setVisible(true);
toFront();
在Windows XP下,它在第一次调用时工作,第二次只有任务栏中的选项卡闪烁,框架不再出现在前面。Win2k也是如此。在Vista上,它似乎运行良好

您有什么想法吗?

javadoc中有许多关于toFront()方法的内容,这些内容可能会导致您的问题

但我还是要猜一猜,当“只有任务栏中的标签闪烁”时,应用程序被最小化了吗?如果是这样,javadoc中的以下行可能适用:


“如果此窗口可见,则将此窗口置于前面,并可能使其成为聚焦窗口。”

Windows具有防止窗口窃取焦点的功能;相反,它会闪烁任务栏图标。在XP中,默认情况下它是打开的(我所看到的唯一改变它的地方是使用TweakUI,但是在某个地方有一个注册表设置)。在Vista中,他们可能更改了默认设置和/或使用开箱即用的UI将其作为用户可访问的设置公开

自Windows2K以来,防止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或Java 7上。经过一些调查和实验后,我不得不更新代码,以覆盖窗口的
toFront
方法(与上面修改的代码一起执行):


从Java 8_20开始,此代码似乎运行良好。

一个可能的解决方案是:

java.awt.EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        myFrame.toFront();
        myFrame.repaint();
    }
});

我在Ubuntu(Java1.6.0_10)下把一个
JFrame
放在前面也遇到了同样的问题。我唯一能解决这个问题的方法就是提供一个
WindowListener
。具体地说,我必须将我的
JFrame
设置为每当调用
toFront()
时始终处于顶部,并将
windowDeactivated
事件处理程序设置为
setAlwaysOnTop(false)


因此,下面是可以放入基本
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上调用。

我发现的跨平台不存在不一致性的最简单方法:

setVisible(假);
setVisible(真)

这个简单的方法在Windows 7中非常适合我:

    private void BringToFront() {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                if(jFrame != null) {
                    jFrame.toFront();
                    jFrame.repaint();
                }
            }
        });
    }

在windows和linux中,控制.toFront()使用JFrame时发生的情况的规则是相同的:

->如果现有应用程序的窗口当前是焦点窗口,则焦点将切换到请求的窗口 ->否则,该窗口仅在任务栏中闪烁

但是:

->新窗口自动获得焦点

因此,让我们利用这一点!你想把窗户放在前面,怎么做?嗯:

  • 创建一个空的非用途窗口
  • 表现出来
  • 等待它显示在屏幕上(setVisible执行此操作)
  • 显示时,为实际要将焦点移到的窗口请求焦点
  • 隐藏空窗口,摧毁它
  • 或者,在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);
      }
    });
    

    Hj,在Fedora KDE 14中,你的所有方法都不适用于我。在我们等待Oracle解决此问题时,我有一个肮脏的方法将窗口带到前面

    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 Vista上测试):D

    fullscreen变量表示您希望应用程序全屏运行还是窗口运行


    这不会使任务栏闪烁,但会将窗口可靠地放在前面。

    我测试了你的答案,只为我工作。尽管我无法将窗口恢复到以前的状态(最大化/正常)。我发现这种突变更好:

    view.setState(java.awt.Frame.ICONIFIED);
    view.setState(java.awt.Frame.NORMAL);
    

    setState
    而不是
    setExtendedState

    为避免窗口在隐藏后恢复可见时失去焦点,需要做的是:

    setExtendedState(JFrame.NORMAL);
    
    像这样:

    defaultItem.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    showWindow();
                    setExtendedState(JFrame.NORMAL);
                }
    });
    

    +1支持不允许windows窃取焦点。我讨厌在文档中输入时发生这种情况。我完全同意你反对窃取焦点,但在这种情况下,用户希望应用程序走到最前面。但是更改注册表设置和更改整个windows行为是不酷的
    setExtendedState(JFrame.NORMAL);
    
    defaultItem.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    showWindow();
                    setExtendedState(JFrame.NORMAL);
                }
    });