Java Swing - держать диалоговое окно вверх

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);
    }
}

Выход:

swing-keep-dialog-up-1

Если пользователь пытается закрыть окно, ничего не происходит. Если пользователь нажимает кнопку «Я ЛЮБЛЮ ЧЕРЕПАХОВ», программа показывает следующий диалог и затем закрывается.

swing-keep-dialog-up-2

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);
    }

}

Выход:

swing-keep-dialog-up-1

Если пользователь пытается закрыть окно:

swing-keep-dialog-up-3

Если пользователь нажимает кнопку Esc:

swing-keep-dialog-up-4

Это в значительной степени резюмирует эту механику. Некоторые могут возразить, что обработка пользовательского ввода традиционным способом, при котором мы проверяем возвращаемое значениеJOptionPane, более эффективно с точки зрения ресурсов. Может быть, а может и нет; в зависимости от остальной части кода эта механика может быть недостающей частью. Однако можно сказать наверняка, что чем больше вы знаете, тем выше вероятность того, что вы сделаете правильный выбор.