Как сделать JDialog не всегда поверх родительского

У меня есть JFrame, который порождает два JDialogs. Каждое из трех окон должно быть фокусируемым (и это то, как я сейчас написал), но этот JFrame не будет отображаться поверх диалогов. Когда вы щелкаете по любому диалоговому окну, они появляются друг над другом (как и следовало ожидать), но этот JFrame просто отказывается выходить на передний план.

Мне нужно, чтобы они оставались JDialogs (в отличие от самих JFrames), поскольку большая часть текущего поведения желательна (например, когда другое окно / приложение блокирует любое или все окна, если вы выберете любое из окон, все они выйдут на передний план (тогда как три JFrames приведут к выходу только выбранного)).

Мои конструкторы JDialogs предназначены для этого:

SubDialog(JFrame parent /*, a handful, ofOther arguments */){
    super(parent, ModalityType.MODELESS); //not even the modeless helped
    setAlwaysOnTop(false); //not even the not always on top helped
    setUndecorated(true); //maybe this has something to do with it (unlikely, just fyi)?

    //some simple variable assignments

}

Я даже попытался закинуть setAlwaysOnTop(true) в свой JFrame. Никаких кубиков. Я был в отчаянии и даже попробовал одно из этих чисел:

MyJFrame(String title){
    super(title);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    addWindowFocusListener(new WindowAdapter(){
        public void windowGainedFocus(WindowEvent e){
            final Window w = e.getWindow();

            //PLEASE come to the front
            w.toFront();

            //even MOAR desperation
            SwingUtilities.invokeLater(new Runnable(){
                public void run(){
                    w.toFront(); //STILL no dice.
                }
            });
        }
    });
}

Мысли? Я ничего не получил.


person captainroxors    schedule 07.03.2014    source источник
comment
Я думаю, вы имеете в виду ModalityType.MODELESS, а не ModalityType.MODELESS? Также попробуйте вызвать setModal (false);   -  person dberm22    schedule 08.03.2014
comment
Ой. Хороший глаз. Орфография исправлена. Установка ModalityType.MODELESS идентична вызову setModal (false). Фактически, вызов setModal (false) фактически изменяет тип модальности на MODELESS. Я все равно попробовал, на всякий случай. Никаких кубиков.   -  person captainroxors    schedule 08.03.2014


Ответы (2)


Как сделать JDialog не всегда поверх родительского

Как указано в этом вопросе и ответе: проблема setModal с двумя Jdialogs внутри Jframe:

Это поведение зависит от того, как собственная оконная система обрабатывает сфокусированные и активные окна. Сказав это, если вы вызываете, например, toFront () он попытается разместить окно наверху стека, НО некоторые платформы не позволяют окнам, которым принадлежат другие окна, появляться поверх своих дочерних окон. То же самое происходит, когда вы вызываете toBack (). См. Javadocs для получения более подробной информации.

Например, в Windows 7 родительский диалог становится сфокусированным, но его дочерние элементы по-прежнему отображаются (не сфокусированы) вверху. Как упоминалось выше, оконная система решает, как решить эту проблему.

person dic19    schedule 08.03.2014
comment
Другими словами, Этого нельзя сделать [чисто]. Я этого боялся. - person captainroxors; 10.03.2014
comment
@captainroxors, к сожалению, ты прав. Просто обходной путь - создание БЕСПЛАТНЫХ диалогов без родителя. Затем вы можете вынести раму вперед. - person dic19; 10.03.2014

Этого очень легко добиться, см. Следующий код:

    JFrame frame = new JFrame();
    frame.setBounds(0,0,400,200);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

// Special attention to this line, do not use same JFrame, create a dummy JFrame
// If you want to save memory you can also use new JDialog((JFrame)null)
    JDialog jd = new JDialog(new JFrame());
    jd.setModalityType(Dialog.ModalityType.MODELESS);
    jd.setBounds(0,0,100, 100);
    jd.setVisible(true);
person Sourabh Bhat    schedule 07.03.2014
comment
Что ж, да, благодаря этому диалоги и фрейм могут накладываться друг на друга, но теперь они больше не связаны. Создание этого фиктивного JFrame эквивалентно тому, что родительский фрейм не передается в конструктор. Это разрушает исходное поведение, о котором я упоминал, то есть когда другое окно / приложение блокирует любое или все окна, если вы выберете любое из окон [моего приложения], они ВСЕ выйдут на передний план (выделено мной). На тот момент у меня может быть три независимых JFrames. - person captainroxors; 08.03.2014
comment
Разрешите перефразировать ваш вопрос. Итак, если A - это JFrame, B и C - это JDialog с родительским A, а D - это еще один JFrame. Что вы хотите: 1) Если выбрано A, когда B и C находятся выше, тогда B и C должны быть ниже, 2) Если D активен, а A нажата, при нажатии B и C должны появиться всплывающие окна? Интересно, зачем вам такое поведение? - person Sourabh Bhat; 08.03.2014
comment
Вместо того, чтобы думать о JFrame D (я предполагаю, что вы имели в виду проживание в той же JVM), я имею в виду выполнение совершенно другого приложения, например Photoshop, Firefox, Windows Explorer (ничего даже отдаленно не связанного с моим Java-приложением). Итак, да, я определенно хочу, чтобы B и C отображались при выборе A (т.е. все приложение отображается перед всеми остальными), и, поскольку было выбрано A, я ожидаю, что оно будет отображаться поверх B и C. Есть ли в этом смысл? Приносим извинения за то, что четко не передали мои намерения. - person captainroxors; 08.03.2014