簡體   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