2015-12-24 12 views
0

У нас был запрос, что некоторые диалоги всегда должны быть сверху, основываясь на каком-то элементе управления. Это необходимо включить/выключить для каждого диалога. Используя следующий код, и пройдя через следующие шаги, мне кажется, как ошибка Java:Развернуть несколько диалоговых окон сверху вниз не работают независимо, если у них один и тот же владелец

  1. Набор Dialog1 на вершине. Проверьте, что он остается на вершине.
  2. Установить dialog2 сверху. Проверьте, что оба диалога остаются на вершине.
  3. Установить диалог1 не сверху.

Ожидаемое: Dialog2 остается на вершине и Dialog1 не

Фактический: ни один из диалогов не остаются на вершине.

Это имеет некоторую связь с владельцем диалогов. Если вы раскомментируете комментарии к блоку, все работает так, как ожидалось, но я не думаю, что это нормальное поведение, так как Always on Top не должен быть связан с родителем. Это нормально или это проблема с Swing? К сожалению, установка нового владельца для каждого диалогового окна вызывает другие проблемы.

public static void main(String[] args) { 
    final JFrame rahan = new JFrame("Rahan"); 
    rahan.setSize(new Dimension(1000,1000)); 
    rahan.setVisible(true); 


    JDialog d1 = getJDialog(/*new JFrame()*/); 
    JDialog d2 = getJDialog(/*new JFrame()*/); 
} 

private static JDialog getJDialog(/*JFrame owner*/) { 
    final JDialog jDialog = new JDialog(/*owner*/); 
    final JButton onTop = new JButton("OnTop"); 
    onTop.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      jDialog.setAlwaysOnTop(!jDialog.isAlwaysOnTop()); 
     } 
    }); 
    jDialog.add(onTop); 
    jDialog.setVisible(true); 
    jDialog.pack(); 
    return jDialog; 
} 
+1

Вы хотите модальный диалог? –

+0

К сожалению, да. Приложение заполнено модальными диалогами для всех видов подтверждений. –

+0

Извините, мой плохой. Я думал о другом случае. Ни один из диалогов не должен или будет модальным. –

ответ

1

Если я запустить приложение, как это:

public static void main(String[] args) { 
    final JFrame rahan = new JFrame("Rahan"); 
    rahan.setSize(new Dimension(1000,1000)); 
    rahan.setVisible(true); 


    JDialog d1 = getJDialog(rahan); 
    JDialog d2 = getJDialog(rahan); 
} 

    private static JDialog getJDialog(JFrame owner) { 
     final JDialog jDialog = new JDialog(owner); 
     final JButton onTop = new JButton("OnTop"); 
     onTop.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(java.awt.event.ActionEvent e) { 
       jDialog.setAlwaysOnTop(!jDialog.isAlwaysOnTop());  
      } 
     }); 
     jDialog.add(onTop); 
     jDialog.setVisible(true); 
     jDialog.pack(); 
     return jDialog; 
    } 

    } 

Он отлично работает. Два диалоговых окна всегда сверху, и это не модально, поэтому вы можете щелкнуть по кадру.

Вы можете попробовать установить диалог модальным, как это:

jDialog.setModal(true); 

Но это своего рода идти против того, что вы достигаете правильно?

+0

Модальные диалоги, скрытые AlwaysOnTopDialogs, - это еще одна проблема, с которой я столкнулся, но, к сожалению, в вашем примере 2 диалоги всегда находятся поверх фрейма. Кнопка больше не работает для переключения статуса «AlwaysOnTop» по отношению к кадру. Кроме того, моя проблема все еще не решена. Попробуйте использовать браузер в качестве сравнения и сделайте 3 шага, которые я представил. Проблема все еще присутствует, если диалоги имеют один и тот же родительский элемент. –

+0

Я думаю, вы имеете в виду: если вы нажмете кнопку, то диалог должен перейти в начало? –

+0

Я имею в виду, что они должны работать независимо. Если оба на передней панели и вы отключите один из них, оба будут работать под браузером, а не только с отключенным. –

1

Рассматривая код для setAlwaysOnTop, они отправляются непосредственно в одноранговую систему, поэтому это может быть проблема, зависящая от ОС.

Во-вторых, вы пробовали делать все создание в потоке отправки событий? Это было предложено в предыдущей статье по этому вопросу.

JDialog.setAlwaysOnTop(true) brings all dialogs to the front under Windows

+0

Такое же поведение, даже если все сделано на EDT. Опять же, моя проблема в том, что они не действуют независимо, имея одного и того же владельца. Если оба диалога всегдаOnTop, и я установил, что один из них больше не будет AlwaysOnTop, они оба перестанут быть на высоте. Я не думаю, что это нормальное поведение, так как владелец не должен влиять на это. –

1

Не уверен, что если этот вопрос по-прежнему актуален, но я нашел обходной путь потенциальных проблем. Если вы сохраните список всех потенциально «Всегда поверх», которые вы добавляете каждый раз, когда создается новый, вы можете вернуться и снова включить их, а затем снова включить их, как они должны быть.

ArrayList<Window> = new ArrayList<Window>(); 
. 
. 
. 
void createWindow() { 
    Window w = new Window(); 
    windowList.add(w); 
} 

Затем, когда один из окна «Always On Top» кнопка выключена, вернитесь к windowList и переключать все те, которые установлены всегда на вершине. Следующее должна быть в вашей actionPerformed функции у слушателя действий для переключей «Всегда сверху»:

if (!windowAlwaysOnTopButton.isSelected()) { 
    ArrayList<Window> turnedOff = new ArrayList<Window>(); 
    for (Window w : windowList) { 
     if (w.isAlwaysOnTop()) { 
      w.setAlwaysOnTop(false); 
      turnedOff.add(w); 
     } 
    } 
    for (Window w : turnedOff) { 
     w.setAlwaysOnTop(true); 
    } 
} 

Вам нужны два для петель и список turnedOff, потому что если вы переключаетесь каждый, затем снова включите в том же loop, вы столкнулись с исходной проблемой, если Windows A и B всегда находятся сверху, тогда окно A выключается, окно B также будет отключено. Вот почему вам нужно выключить их, а затем снова прокрутить, чтобы снова включить их.Я понимаю, что это может быть хакерское решение, но если это сработает для меня, это может сработать для вас. Ура!

+0

Ну, это уже не актуально, поскольку у нас уже есть решение на месте (если я правильно помню), имеющего нового владельца для каждого диалога, но я согласен, что ваше решение работает, даже если оно выглядит хакером. Хотя все еще не уверен, почему он работает так, как он. –