33 votes

Comment fermer un JDialog et faire en sorte que les récepteurs d'événements de la fenêtre soient notifiés ?

Existe-t-il un moyen de fermer un JDialog par le biais du code de sorte que les auditeurs d'événements de la fenêtre soient toujours notifiés ? J'ai essayé d'attribuer la valeur false à visible et de le fermer, mais ni l'un ni l'autre ne semble fonctionner.

48voto

David Moles Points 7669

Fermeture d'une fenêtre (avec dispose() ) et le cacher (avec setVisible(false) ) sont des opérations différentes, et produisent des événements différents -- et le fermer à partir du système d'exploitation est encore une autre opération différente qui produit encore un événement différent.

Tous trois produiront windowDeactivated pour vous dire que la fenêtre a perdu le focus, mais dispose() produira alors windowClosed tandis que la fermeture du système d'exploitation premièrement produire windowClosing . Si vous voulez traiter ces deux cas de la même manière, vous pouvez configurer la fenêtre pour qu'elle soit éliminée à la fermeture :

window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

En général, setVisible(false) implique que vous pourriez vouloir utiliser la fenêtre à nouveau, donc il n'affiche 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 fonction ComponentListener ;

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

Notez cependant que cela ne fonctionnera que pour les fichiers explicites setVisible() appels. Si vous avez besoin de détecter le masquage de manière plus générale, vous pouvez utiliser une fonction HierarchyListener mais c'est probablement plus de problèmes que ça n'en 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 disposez d'une fenêtre, vous obtenez un couple de HierarchyEvent d'abord pour le masquage et ensuite pour l'invalidation, mais lorsque vous le masquez à l'aide de setVisible() il est toujours valide, donc vous n'aurez pas l'invalidation.

3voto

Joseph Gordon Points 950

Je ne semble pas avoir votre problème. Lorsque j'utilise le code ci-dessous fenêtreDésactivée() est appelé soit pour setVisible( false ) o [dispose()](http://java.sun.com/javase/6/docs/api/java/awt/Window.html#dispose()) y 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);
    }
}

1voto

camickr Points 137095

Envoi d'un événement windowClosing à la fenêtre. Consultez l'exemple d'ExitAction dans le manuel de l'utilisateur. Clôture d'une demande l'entrée.

0voto

Grundlefleck Points 29486

Suggestion non testée :

Avez-vous essayé d'utiliser getWindowListeners(), puis d'itérer pour envoyer windowClosed() à chacun des WindowListeners ?

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

J'ai bien peur que le fait d'appeler dialog.dispose() fonctionne bien pour moi dans mon exemple simple.

0voto

Je voulais tirer un windowClosing à partir du code (comme si l'utilisateur avait cliqué sur le X), parce que j'ai un bouton de fermeture supplémentaire dans le JDialog et que je veux que le même WindowListener (que j'ai implémenté en utilisant un fichier WindowAdapter ) à exécuter lorsque le X est cliqué et lorsque le bouton est cliqué. Exécution de dispose() uniquement les feux windowClosed pas windowClosing et je veux qu'un message apparaisse avant la fenêtre est fermée, pour confirmation. Je n'ai pas non plus réussi à tirer windowClosing via la méthode de JDialog processWindowEvent puisqu'il est protégé.

Voici comment je l'ai fait fonctionner :

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

J'espère que cela aidera quelqu'un.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X