web-dev-qa-db-fra.com

Comment puis-je fermer un JDialog et informer les auditeurs de l'événement de fenêtre?

Existe-t-il un moyen de fermer un JDialog via un code tel que les écouteurs d'événements Windows soient toujours notifiés? J'ai essayé simplement de mettre visible en false et d'éliminer, mais aucun ne semble le faire.

33
Jeff Storey

La fermeture d'une fenêtre (avec dispose()) et son masquage (avec setVisible(false)) sont des opérations différentes, qui produisent différents événements. La fermeture de cette fenêtre à partir du système d'exploitation est une autre opération différente qui produit encore un événement différent.

Tous les trois produiront windowDeactivated pour vous dire que la fenêtre est perdue, mais dispose() produira alors windowClosed, tandis que fermer à partir du système d'exploitation produira premier produira windowClosing. Si vous souhaitez gérer les deux de la même manière, vous pouvez définir la fenêtre à supprimer à la fermeture:

window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

En règle générale, setVisible(false) implique que vous souhaitiez peut-être utiliser à nouveau la fenêtre, de sorte qu'elle n'envoie aucun événement de fenêtre (à l'exception de windowDeactivated). Si vous souhaitez détecter le masquage d'une fenêtre, vous devez utiliser une variable ComponentListener;

window.addComponentListener(new ComponentAdapter() {
  @Override
  public void componentHidden(ComponentEvent e) {
    System.out.println("componentHidden()");
  }
})

Notez cependant que cela ne fonctionnera quasiment que pour les appels explicites setVisible(). Si vous avez besoin de détecter la dissimulation de manière plus générale, vous pouvez utiliser un HierarchyListener, mais c'est probablement plus ennuyant que cela ne vaut la peine.

  window.addHierarchyListener(new HierarchyListener() {
    @Override
      public void hierarchyChanged(HierarchyEvent e) {
        System.out.println("valid: " + window.isValid());
        System.out.println("showing: " + window.isShowing());
      }
  });

Notez que lorsque vous supprimez une fenêtre, vous obtenez quelques HierarchyEvents, d'abord pour masquer, puis pour invalider, mais lorsque vous la masquez avec setVisible(), elle est toujours valide, de sorte que vous n'obtiendrez pas l'invalidation.

48
David Moles

Je ne semble pas avoir votre problème. Lorsque j'utilise le code ci-dessous windowDeactivated () est appelé pour setVisible (false) ou dispose () et windowClosed () est également appelé pour dispose (). 

ClosingDialog.Java:

public class ClosingDialog extends JDialog {
    public ClosingDialog(Frame owner, String title, boolean modal) {
        super(owner, title, modal);
        JPanel contentPanel = (JPanel) this.getContentPane();

        JButton setVisButton = new JButton("setVisible( false )");
        setVisButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ClosingDialog.this.setVisible(false);
            }
        });

        JButton disposeButton = new JButton("dispose()");
        disposeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ClosingDialog.this.dispose();
            }
        });

        contentPanel.setLayout(new FlowLayout());

        contentPanel.add(setVisButton);
        contentPanel.add(disposeButton);

        this.addWindowListener(new WindowListener() {
            public void windowActivated(WindowEvent e) {
                System.out.println("windowActivated");
            }

            public void windowClosed(WindowEvent e) {
                System.out.println("windowClosed");
            }

            public void windowClosing(WindowEvent e) {
                System.out.println("windowClosing");
            }

            public void windowDeactivated(WindowEvent e) {
                System.out.println("windowDeactivated");
            }

            public void windowDeiconified(WindowEvent e) {
                System.out.println("windowDeiconified");
            }

            public void windowIconified(WindowEvent e) {
                System.out.println("windowIconified");
            }

            public void windowOpened(WindowEvent e) {
                System.out.println("windowOpened");
            }
        });

        this.setSize(300, 300);
    }
}
3
Joseph Gordon

Distribuer un événement windowClosing à la fenêtre. Consultez l'exemple ExitAction à partir de l'entrée Fermeture d'une application .

1
camickr

Suggestion non testée:

Avez-vous déjà essayé getWindowListeners (), puis parcourez itérativement pour envoyer windowClosed () à chacun des WindowListeners?

EDIT: la suggestion ci-dessus est fausse. Garder pour la postérité. 

J'ai peur d'appeler dialog.dispose () pour moi, dans mon exemple simple.

0
Grundlefleck

Je voulais déclencher un événement windowClosing à partir du code (comme si l'utilisateur cliquait sur X), car j'ai un bouton de fermeture supplémentaire dans JDialog et que je souhaite utiliser le même WindowListener (que j'ai mis en œuvre à l'aide de WindowAdapter) lorsque est cliqué et quand le bouton est cliqué. L'exécution de dispose() ne déclenche que windowClosed, pas windowClosing, et je souhaite qu'un message apparaisse avant la fenêtre est fermée pour confirmation. Je n'ai pas non plus réussi à déclencher windowClosing via la méthode processWindowEvent de JDialog car elle est protégée.

Voici comment je l'ai fait fonctionner cependant:

WindowAdapter adapter = (WindowAdapter)jdialog.getWindowListeners()[0];
adapter.windowClosing(new WindowEvent((Window)jdialog, WindowEvent.WINDOW_CLOSING));

J'espère que ça aide quelqu'un.

0
user2443802