# Netbeans-Anwendung schliessen



## heidiweber (4. Sep 2008)

Hallo,

ich habe mit Netbeans 6.1 eine Standard-MDI-Anwendung erstellen lassen.

Das Projekt besteht u.a. aus.
FrameView
JPanel
JMenuBar
statusBar

Ich möchte die Möglichkeit haben, wenn man die Anwendung schliesst (z.B. durch klick auf das X rechts oben), zuerst zu fragen, ob noch die geänderten Daten gespeichert werden sollen. Oder evtl. dass man das schliessen sogar verhindern kann.

Bei einem JDialog habe ich ja ein Windowsclosing bzw. WindowsClosed -> da ist es kein Problem. Aber bei der "Haupt-MDI"-Anwendung nicht.

Wie kann man sowas realisieren?

Vielen Dank für die Hilfe
Heidi


----------



## André Uhres (6. Sep 2008)

Das entsprechende Window Event können wir auch an den JFrame hängen. 
Die DefaultCloseOperation setzen wir dann auf DO_NOTHING_ON_CLOSE.


----------



## heidiweber (6. Sep 2008)

Ich habe aber leider kein JFrame.

In Netbeans kann ich leider nirgends in den Properties (in der Mitte auf der rechten Seite) zu den entsprechenden Containern (siehe erste Posting) diesbzgl. was einstellen. Bei einem JFrame geht das. Aber nicht bei der Konstellation, die Netbeans standardmäßig anlegt - oder?


----------



## André Uhres (7. Sep 2008)

Versuch Folgendes: such im Quellcode nach "initComponents();".
Dort fügst du dies ein:

```
initComponents();
        getFrame().setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getFrame().addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(java.awt.event.WindowEvent evt) {
                System.out.println("windowClosing");
            }
        });
```


----------



## heidiweber (7. Sep 2008)

Guten Morgen,

das schaut doch schon mal nicht schlecht aus

Ich habe das bis jetzt so:


```
getFrame().setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
        getFrame().addWindowListener(new java.awt.event.WindowAdapter() { 
            @Override 
            public void windowClosing(java.awt.event.WindowEvent evt) { 
                System.out.println("windowClosing"); 
                int res = JOptionPane.showConfirmDialog(null, "Möchten sie die geänderten Werte Speichern?", "Speichern?", JOptionPane.YES_NO_CANCEL_OPTION);

                if (res == 0) {
                    // YES gedrueckt
                } else if (res == 1) {
                    // NO gedrueckt
                } else {
                    // Cancel gedrueckt
                    
                    // Was muss hier rein, damit das Formular nicht geschlossen wird?
                }

            } 
        });
```

Wie kann ich noch verhindern, dass das Formular geschlossen wird, wenn der User auf Abbrechen klickt?

Dachte erst, dass ich die DefaultCloseOperation auf DO_NOTHING_ON_CLOSE setzte und dann händisch das Formualr schliesse. Jedoch hat dies keinen Einfluss, das Formular wird trotzdem geschlossen:


```
getFrame().setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
```

Kannst du mir bitte noch einen Tipp geben?
Wünsch dir einen schönen Sonntag
Grüße
Heidi


----------



## André Uhres (7. Sep 2008)

So müsste es gehen:

```
public class DesktopApplication3View extends FrameView {
...
//Du musst natürlich "desktopapplication3.DesktopApplication3" und "DesktopApplication3View" 
//durch deine Package/Klassen-Namen ersetzen:
        javax.swing.ActionMap actionMap = org.jdesktop.application.Application
                .getInstance(desktopapplication3.DesktopApplication3.class)
                .getContext().getActionMap(DesktopApplication3View.class, this);
        actionMap.put("quit", new AbstractAction("Exit") {
            public void actionPerformed(ActionEvent e) {
                quit();
            }
        });
        initComponents();
        initWindowListener();
```


```
private void quit() {
        int res = JOptionPane.showConfirmDialog(null, "Möchten sie die geänderten " +
                "Werte Speichern?", "Speichern?", JOptionPane.YES_NO_CANCEL_OPTION);
        if (res == 0) {
            // YES gedrueckt
            getFrame().dispose();
        } else if (res == 1) {
            // NO gedrueckt
            getFrame().dispose();
        } else {
            // Cancel gedrueckt
        }
    }
    private void initWindowListener() {
        Runnable init = new Runnable() {
            public void run() {
                //Die WindowListener vom "Swing Application Framework" ausschalten:
                WindowListener[] windowListeners = getFrame().getWindowListeners();                
                for (WindowListener windowListener : windowListeners) {
                    getFrame().removeWindowListener(windowListener);
                }
                //Eigenen WindowListener hinzufügen:
                getFrame().setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
                getFrame().addWindowListener(new java.awt.event.WindowAdapter() {
                    @Override
                    public void windowClosing(java.awt.event.WindowEvent evt) {
                        quit();
                    }
                });
            }
        };
        SwingUtilities.invokeLater(init);
    }
```
Ich kenne das "Swing Application Framework" nicht so gut und weiss daher nicht, ob es vielleicht eine elegantere Lösung gibt :wink:


----------



## heidiweber (10. Sep 2008)

Vielen Dank André für die spitzen Hilfe. Ich habe es hinbekommen

Aber ich habe noch eine Frage:

Ich habe nur die Methoden "quit" und "initWindowListener" eingebaut - und rufe die dann einfach so auf:


```
initComponents(); 
initWindowListener();
```

Funktioniert. 

Für was ist dann dies:


```
javax.swing.ActionMap actionMap = org.jdesktop.application.Application 
                .getInstance(desktopapplication3.DesktopApplication3.class) 
                .getContext().getActionMap(DesktopApplication3View.class, this); 
        actionMap.put("quit", new AbstractAction("Exit") { 
            public void actionPerformed(ActionEvent e) { 
                quit(); 
            } 
        });
```

Kannst du oder sonst jemand mir bitte das noch erklären? Ich wills ja auch zumindest einigermassen verstehen, was ich mache.

Ich habe zwar schon gegoogelt:



> Eine ActionMap beinhaltet die Verknüpfung von Schlüsseln bzw. Action-Namen zu Action-Exemplaren. Typischerweise wird diese Klasse mit einer InputMap verwendet. Wenn eine Eltern-ActionMap angegeben wurde wird auch in der gesucht, wenn in der aktuellen der Wert nicht gefunden werden konnte.



Aber was heisst das auf Deutsch? Und brauche ich das actionMapping, wenns auch ohne geht?

Grüße
Heidi


----------



## André Uhres (15. Sep 2008)

heidiweber hat gesagt.:
			
		

> brauche ich das actionMapping, wenns auch ohne geht?


Natürlich nicht. Die Menubar vom Framework benutzt aber Actions. Falls du das Programm auf diesem Weg beenden willst,
 dann brauchst du wahrscheinlich den angegebenen Code.
(Sry für die verspätete Antwort, war in Urlaub.)


----------



## heidiweber (15. Sep 2008)

Alles klar (Das Handling der Menübar macht Netbeans für mich - rufe beim Beenden-Button einfach Quit() auf).

Vielen Dank nochmal für die Hilfe. Du hast mir super weitergeholfen.

Schönen Abend noch

Grüße
Heidi


----------

