Java Swing - держать диалоговое окно вверх
Наиболее распространенный способ(and simple) реализовать диалог в нашем приложении - это классJOptionPane
. В этой статье мы обсудим, как «перезаписать» поведение по умолчаниюJOptionPane
, которое закрывает диалоговое окно, когда пользователь нажимает кнопку, созданнуюJOptionPane
.
Прежде чем перейти к примерам, нам нужно знать, что когда мы используемJOptionPane
в нашем приложении, то, что действительно выполняется за кадром, является модальнымJDialog
. JOptionPane
- это контейнер, который автоматически создаетJDialog
и добавляет себя кcontent pane
.
1. Основной пример
В этом примере мы останавливаем автоматическое закрытие диалогового окна и вместо этого обрабатываем его самостоятельно, реализуя прослушивательPropertyChange
. Приведенный ниже пример является абсолютной основой для реализации этого механизма в вашем коде, поскольку здесь нет обработки взаимодействия с пользователем или проверки ввода.
KeepDialogUp.java
package com.techfou.stayup; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.ImageIcon; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; public class KeepDialogUp { public static void main(String[] args) { JFrame frame = new JFrame(); ImageIcon icon = new ImageIcon("src/images/turtle64.png"); Object[] options = {"I DO LOVE TURTLES"}; JOptionPane jop = new JOptionPane("Admit your love for turtles\nor you shall not pass!!" , JOptionPane.ERROR_MESSAGE, 0, icon, options, options[0]); JDialog dialog = new JDialog(frame, "You LOVE turtles", true); dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); dialog.setContentPane(jop); jop.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (JOptionPane.VALUE_PROPERTY.equals(evt.getPropertyName())) { dialog.dispose(); JOptionPane.showMessageDialog(null, "Good for you >:P"); System.exit(0); } } }); dialog.pack(); dialog.setLocationRelativeTo(frame); dialog.setVisible(true); } }
Выход:
Если пользователь пытается закрыть окно, ничего не происходит. Если пользователь нажимает кнопку «Я ЛЮБЛЮ ЧЕРЕПАХОВ», программа показывает следующий диалог и затем закрывается.
2. Пример со слушателями
Теперь давайте оживим предыдущий пример. Мы добавимwindowListener
для обработки попытки пользователя закрыть диалоговое окно, и мы проверим ввод пользователя вpropertyChangeListener
.
KeepDialogUpExtended.java
package com.techfou.stayup; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.ImageIcon; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; public class KeepDialogUpExtended { public static void main(String[] args) { JFrame frame = new JFrame(); ImageIcon icon = new ImageIcon("src/images/turtle64.png"); Object[] options = {"I DO LOVE TURTLES"}; JOptionPane jop = new JOptionPane("Admit your love for turtles\nor you shall not pass!!", JOptionPane.ERROR_MESSAGE, 0, icon, options, options[0]); JDialog dialog = new JDialog(frame, "You LOVE turtles", true); dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); dialog.setContentPane(jop); dialog.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { JOptionPane.showMessageDialog(frame, "YOU SHALL NOT PASS", "!!", JOptionPane.ERROR_MESSAGE); } }); jop.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (JOptionPane.VALUE_PROPERTY.equals(evt.getPropertyName())) { if (jop.getValue().equals(options[0])) { dialog.dispose(); JOptionPane.showMessageDialog(null, "Good for you >:P"); System.exit(0); } else { JOptionPane.showMessageDialog(frame, "There is no\n>> ESC <<", "You little shenanigan...", JOptionPane.ERROR_MESSAGE); } } } }); dialog.pack(); dialog.setLocationRelativeTo(frame); dialog.setVisible(true); } }
Выход:
Если пользователь пытается закрыть окно:
Если пользователь нажимает кнопку Esc:
Это в значительной степени резюмирует эту механику. Некоторые могут возразить, что обработка пользовательского ввода традиционным способом, при котором мы проверяем возвращаемое значениеJOptionPane
, более эффективно с точки зрения ресурсов. Может быть, а может и нет; в зависимости от остальной части кода эта механика может быть недостающей частью. Однако можно сказать наверняка, что чем больше вы знаете, тем выше вероятность того, что вы сделаете правильный выбор.