繁体   English   中英

多个JFrame应用程序,如何将它们放在一起?

[英]Multiple JFrame application, how do I bring them all to front together?

我的用户喜欢拥有多个JFrame 它允许他们调整不同组件的大小,并将它们放置在屏幕上所需的任何位置。 但是,我有一个要求使所有子窗口一起出现在前面...换句话说,假设它们最大化所有窗口前面的另一个窗口,然后使用任务栏单击其中一个JFrame的。 我如何设置它以便它们都排在最前面? 注意:也可以关闭子窗口。 如果它们实际上是隐藏的,我希望它们走在前头。 我有一个ApplicationModel类,用于跟踪窗口是否被隐藏。

我尝试过的事情:

  1. 使用windowActivated()focusGained()尝试将它们全部置于最前面。 这通常会导致无限循环。 问题是我的事件框架从事件调度线程发送这些请求,因此使用AtomicBoolean任何类型的阻塞都不会持续很长时间。
    • 主要问题不是我不能让他们走到最前面……我让他们走到最前面。 问题是他们保持尝试着走到前面,因为将窗口放到前面会抛出focusGained和windowActivated事件,这会产生无限循环。
  2. 将一个窗口设为主窗口,将其他窗口JDialog 不幸的是,这些窗口不是无模式的(因此不会出现在主窗口的前面),或者是模态的(因此会阻塞主窗口)。

如何解决这些问题,或者有完全不同的第三种解决方案?

您可以使用布尔字段作为标志来防止无限循环:

private boolean movingAllFramesToFront;

public void windowActivated(WindowEvent event) {
    if (movingAllFramesToFront) {
        return;
    }

    movingAllFramesToFront = true;

    List<Frame> frames = getAllApplicationFrames();
    for (Frame frame : frames) {
        if (!applicationModel.isHidden(frame)) {
            frame.toFront();
        }
    }

    event.getWindow().toFront();
    event.getWindow().requestFocus();

    EventQueue.invokeLater(new Runnable() {
        public void run() {
            movingAllFramesToFront = false;
        }
    );
}

您可以尝试的另一件事是Java 1.7中引入的新的autoRequestFocus属性。 我从未尝试过使用它,但是这是我对它的工作方式的理解:

public void windowActivated(WindowEvent event) {
    final List<Frame> frames = getAllApplicationFrames();

    for (Frame frame : frames) {
        if (!applicationModel.isHidden(frame)) {
            frame.setAutoRequestFocus(false);
            frame.toFront();
        }
    }

    EventQueue.invokeLater(new Runnable() {
        public void run() {
            for (Frame frame : frames) {
                if (!applicationModel.isHidden(frame)) {
                    frame.setAutoRequestFocus(true);
                }
            }
        }
    );
}

我有一个带有很多Windows的应用程序,并且遇到了与您类似的问题。 我的解决方法是:

@Override
    public void windowActivated(WindowEvent e) {
        if (e.getOppositeWindow() == null) {
            //front every window
        }
    }

首先,我创建了一个类“ SlveFrame”(Slve是我的应用程序的名称),它是“ JFrame”的子级。

public class SlveFrame extends JFrame implements WindowListener {
    static ArrayList<SlveFrame> frames = new ArrayList<SlveFrame>();

    public SlveFrame () {
         addWindowListener(this); / /to make JFrame fire WindowListener's method
    }

    / /... every method added from WindowListener
    @Override
    public void windowActivated(WindowEvent e) {
        if (e.getOppositeWindow() == null) { // return null if window is not from my (or Your) work
            for (SlveFrame frame : frames) { // if you have no idea what this is, look for "for each loop java" in google
                 frame.toFront();
            }
        }
    }

    /**
    * The use of SlveFrame is almost the same as Jframe
    */
    @Override
    public void setVisible (boolean b) {
        if (b) 
            frames.add(this);
        else
            frames.remove(this); // may raise an exception if you're not careful
        super.setVisible(b); //   or your window will simply not be visible.
    }

    @Override
    public void dispose () {
        frames.dispose(this) // may raise an exception you'll want to handle
   }
}


窍门在于, 如果JFrame(或子类)来自您自己的程序 WindowEvent.getOppositeWIndow()返回一个Jframe ,这意味着如果您切换到另一个程序或应用程序(例如eclipse,Firefox或文本编辑器),则返回您的任何窗口,然后调用getOppositeWindow()将返回“ null”。 一个简单的if (e.getOppositeWindow())使得确定您的窗口是否获得焦点的条件相当容易,这种情况要求您将每个窗口都放在最前面,或者放任一切。

setVisible (boolean b)dispose ()的重写是可选的,但允许开发人员将其用作常规窗口。


我希望我能有所帮助。 真诚的〜喇嘛

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM