# Window Listener, Exit, bin am Verzweifeln



## snoop83 (11. Mai 2005)

Fragen über Fragen und ich komme einfach nicht weiter. Nutze "Java ist auch eine Insel" in der 4. Auflage, "Java Core v2" und die Javadocs...

1. mit welchem Befehl muss ich meine Anwendung beenden, damit alle von ihr geöffneten Dialoge mit geschlossen werden? Weder *this.dispose()* noch *System.exit(0)* schließen die noch offnenen Dialoge.

2. wie kann ich einen JDialog bzw. eine JFrame auf modal setzen? (habe z.B. eine JFrame, wo Benutzereingaben gemacht werden müssen, ich bekomm das Teil aber nicht modal gesetzt.. )

3. Ich kann *this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);* nicht verwenden, da ich beim Beenden eine Abfrage brauche. Habe es so versucht:


```
public class Gui extends JFrame {

  public Gui(String title) {
    super(title);
    ...
    this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    this.addWindowListener( new WindowAdapter () { 
         public void WindowClosing(WindowEvent event) {
         menueSpielBeendenClick();
         } 
       }
    );
    ....
    }
}
```

Die entsprechende Methode (menueSpielBeendenClick) wird aber nicht aufgerufen, woran liegts?


----------



## Illuvatar (11. Mai 2005)

1. System.exit (0) schleißt hundertprozentig alles was offen ist

2. JDialog#setModal (true). JFrame geht net modal.

3. mch vllt DO_NOTHING_ON_CLOSE und mach dann in der Methode das dispose(). Aber eigentlich stimmt der Code.


----------



## Roar (11. Mai 2005)

1. System.exit() beendet die ganze VM somit werden auch alle dialoge geschlossen
2. JDialog#setModal() eine Frame kann man nicht modal machen
3. mach was setDefaultCloseOperation im code weg. methoden werden klein geschrieben. du musst die methode windowClosing nennen damit sie aufgerufen wird.


----------



## snoop83 (11. Mai 2005)

toll, dann ist mein java-buch hier irreführend .. da werden eingaben über JFrame's erledigt und vorher wird davon gesprochen, dass diese eingabefenster nach wahl modal oder nicht modal sein können 

kann ich meine bereits gestaltete frame einfach in einen dialog umwandeln? d.h. kann ich problemlos meine buttons, label, größe, position etc. auf einen jdialog übertragen?

System.exit(0) lässt während der Laufzeit vom Programm geöffnete JFrames leider offen
System.exit() geht nicht, Parameter erwartet


wie genau meinst du das mit "du musst die methode windowClosing nennen damit sie aufgerufen wird." so hier:


```
public void windowClosing(WindowEvent event){
    JOptionPane.showMessageDialog(null,"exit"); // Platzhalter, nur Info
  }

  this.addWindowListener( new WindowAdapter () { 
      public void WindowClosing(WindowEvent event) {
      windowClosing(event);
      // menueSpielBeendenClick();
      } 
    }
  );
```

sorry, aber ich versteh immer weniger von diesem Listener-"Mist" ..  :bahnhof:


----------



## mic_checker (11. Mai 2005)

Die Methode heisst windowClosing(...) nicht WindowClosing(...) - das meinte er.


----------



## Roar (11. Mai 2005)

zu system.exit() dann machste eindeutig was falsch :?

zum listener: deine implementierte methode muss windowClosing heissen!


----------



## snoop83 (11. Mai 2005)

sie heißt doch nun
"windowClosing(...)"
oder ist das immernoch falsch?

und System.exit() erwartet bei mir immer einen Parameter:

Zeile:
System.exit();

Fehlermeldung:
The method exit(int) in the type System is not applicable for the arguments ()


----------



## mic_checker (11. Mai 2005)

Das "..." diente nur als Platzhalter, natürlich kommt da "WindowEvent event" für hin.


----------



## Roar (11. Mai 2005)

snoop83 hat gesagt.:
			
		

> und System.exit() erwartet bei mir immer einen Parameter:
> 
> Zeile:
> System.exit();
> ...



uff ja dann gib ihm ein parameter ich bin nur zu faul ihn dahinzuschreiben!


----------



## snoop83 (11. Mai 2005)

@ mic_checker:
ist mir schon klar, dass das nur ein platzhalter war, aber was ist denn nun hier dran noch falsch:


```
public void windowClosing(WindowEvent event){ 
    JOptionPane.showMessageDialog(null,"exit"); // Platzhalter, nur Info 
  }

 this.addWindowListener( new WindowAdapter () { 
      public void WindowClosing(WindowEvent event) { 
      windowClosing(event); 
      // menueSpielBeendenClick(); 
      } 
    } 
  );
```



@ Roar :
wenn ich ihm einen Parameter gebe, z.B. 0, oder 1, oder 2 .. dann bleiben geöffnete JFrames offen 



Desweiteren habe ich nun alle JFrames in JDialogs umgeschrieben, die JLabels, JButtons und JTextfields sind erhalten geblieben, soweit scheint auch alles zu gehen, aber:
Sobald ich meinen JDialog mit this.setModal(true); auf modal setze, reagieren die ActionListener der Buttons nicht mehr. Setze ich die Dialoge nicht auf modal, geht alles anstandslos 



```
public void nameAendernClick(){
  	if (!spielgestartet)
  	  {
  		final MyDialog namedialog = new MyDialog(
  				(int) this.getBounds().getX()+3,    // left
				(int) this.getBounds().getY()+40,   // top
				210, 160,         // width, height
  		"Spielername ändern" );  // title
  		namedialog.getContentPane().setLayout(null);
  		JButton ok = new JButton("OK");
  		JButton cancel = new JButton("Abbrechen");
  		JLabel name = new JLabel("Bitte Spielername eingeben:");
  		final JTextField eingabe = new JTextField("");
  		name.setBounds(     10, 10, 180, 24);
  		eingabe.setBounds(  10, 40, 180, 24);
  		ok.setBounds(       10, 70, 180, 24); // left, top, width, height
  		cancel.setBounds(   10, 100,180, 24);  	
  		namedialog.getContentPane().add(name);  	
  		namedialog.getContentPane().add(eingabe);  	
  		namedialog.getContentPane().add(ok);
  		namedialog.getContentPane().add(cancel);  	
  		namedialog.setResizable(false);
  		namedialog.setModal(true);
  		namedialog.setVisible(true);
  		cancel.addActionListener( new ActionListener(){
  			public void actionPerformed(ActionEvent event){
  				namedialog.dispose();
  				namedialog.setVisible(false);
  			}
  		});
  	
  		ok.addActionListener( new ActionListener(){
  			public void actionPerformed(ActionEvent event){
  				if ( (eingabe.getText().length() > 0) && (eingabe.getText().length() < 16) )
  				{
  					jLabelSpielerName.setText( eingabe.getText() );
  					namedialog.dispose();
  					namedialog.setVisible(false);
  					//daten.setSpielerName( eingabe.getText() ); 
  				}
  				else
  				{ JOptionPane.showMessageDialog(null,
                                       "Der Name muss mindestens 1 Zeichen und maximal 15 Zeichen enthalten!");
  				}
  			}
  		});
  	  }
  	else
  	 { JOptionPane.showMessageDialog(null,
             "Der Name kann während eines Spiels nicht geändert werden!");
  	 }
  }



    jMenuItemNameAendern.addActionListener(new ActionListener(){
    	public void actionPerformed(ActionEvent event){
    		nameAendernClick();
    	}
    }
```


wobei



```
class MyDialog extends JDialog {
	public MyDialog(int left, int top, int width, int height, String title){
		this.setBounds(left, top, width, height);
		this.setTitle(title);
	}
}
```


----------



## mic_checker (11. Mai 2005)

```
public void WindowClosing(WindowEvent event) {
```
-> umbenennen.


----------



## snoop83 (11. Mai 2005)

```
public class Gui extends JFrame {

  public Gui(String title) {
    super(title);
    ....
    //this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
    //this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    this.addWindowListener( new WindowAdapter () { 
        public void WindowClosing(WindowEvent event) {
        WindowClosing(event);
        } 
      }
  }


  public void WindowClosing(WindowEvent event){
  	System.out.println("exit"); // < funzt nicht
  	JOptionPane.showMessageDialog(null,"exit"); // < funzt auch nicht
  	// menueSpielBeendenClick(); // genauso wenig :(
  }
```

ich lass dir den code auch gern per Mail zukommen.. aber: es will einfach nicht, keine chance


----------



## mic_checker (11. Mai 2005)

Arg, schau dir bitte mal das an. Warum rufst du innerhalb von *windowClosing* ne gleichnamige Methode auf und machst es nicht direkt in der anonymen Klasse?


----------



## snoop83 (11. Mai 2005)

ooh.. verdammt, ja, das wüsst ich auch gern.

Aber, ich weiß warum: Weil ich schon 5 Stunden vor dem Quelltext sitze und irgendwann sieht man sowas einfach nicht mehr ..


```
this.addWindowListener( new WindowAdapter () { 
        public void windowClosing(WindowEvent event) {
          	System.out.println("exit");
          	JOptionPane.showMessageDialog(null,"exit");
          	menueSpielBeendenClick();
        } 
      }
    );
```

so gehts natürlich auf Anhieb .. Danke für die Hilfe!


gut, nun muss ich nur noch rausfinden, warum meine JDialogs nur funktionieren, wenn sie nicht modal sind ?!?! 
*edit*:
problem gelöst,
this.setModal(true); muss einfach nur als letztes aufgerufen werden *arg* ... ist mir jetzt auch klar, warum...



*edit*:
kann ich denn direkt beim windowClosing selbiges noch verhindern?
z.b. per ConfirmDialog?


----------



## L-ectron-X (12. Mai 2005)

So in etwa:


```
private void exit() {
  int answer = -1;
  Toolkit.getDefaultToolkit().beep();

  answer = JOptionPane.showConfirmDialog(null, "Möchten Sie die Anwendung wirklich beenden?",  "Programm beenden", JOptionPane.YES_NO_OPTION);

  switch(answer) {
    case JOptionPane.YES_OPTION:
      System.exit(0);
  }
}
```


----------



## Roar (12. Mai 2005)

@lex: und wenn der benutzer nein auswählt? 
@snoop: weiß nich, musst mal probieren ob das geht wenn du das ewevt abfängst (onsume())


----------



## thE_29 (12. Mai 2005)

DU MUSST sagen setDefaultClosingOperation(DO_NOTHING_ON_CLOSE);


Dh, einfach nur, wenn man auf das X drückt, das sich der frame net invisible machen soll!!


Dh, ABER NICHT, das die windowClosing, etc Methoden nicht aufgerufen werden (die werden trotzdem aufgerufen)

Nur wenn man sagt, do_nothing... muss man halt selber dispose oder setVisible(false) sagen

Das is der Unterschied!


----------



## snoop83 (12. Mai 2005)

es geht nicht ... geöffnete JFrames bleiben weiterhin offen.

Quelltext-Auszug:


```
import java.awt.Toolkit;
import javax.swing.JOptionPane;

public class Anwendung {
  public static Spieldaten spieldaten;
  public static Netzwerk netzwerk;
  public static Gui fenster;
	
	
  public static void main(String[] args){
  	spieldaten = new Spieldaten();
  	fenster = new Gui("Muehle");
  }
  
  public static void exitprog() { 
	  int answer = -1; 
	  Toolkit.getDefaultToolkit().beep(); 

	  JOptionPane.showConfirmDialog(null,
             "Möchten Sie die Anwendung wirklich beenden?",
             "Programm beenden", JOptionPane.YES_NO_OPTION); 

	  switch(answer) { 
	    case JOptionPane.YES_OPTION: 
	      System.exit(0); 
	  } 
	}
  
}


------------------------------------------
------------------------------------------


public class Gui extends JFrame {

public Gui(String title) {
  super(title);
  this.setBounds(150,50,600,600);  
  contentPane = (JPanel) this.getContentPane();
  contentPane.setLayout(null);
  itemsAnordnen();
  this.setJMenuBar(jMenuBar);
  this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
  this.addWindowListener( new ListenerSpielBeenden()); //hier
  // meckert er rum:
  // Severity	Description	Resource	In Folder	Location	Creation Time
  // The method addWindowListener(WindowListener) in the type Window is not
  // applicable for the arguments (ListenerSpielBeenden)	Gui.java
  // Anwendung	line 155	12. Mai 2005 18:36:43
  this.setResizable(false);
  this.setVisible(true);
}



------------------------------------------
------------------------------------------


public class ListenerProgrammBeenden implements ActionListener {

	public ListenerProgrammBeenden() {
	}

	public void actionPerformed(ActionEvent e) {
		//Anwendung.fenster.menueProgrammBeendenClick();
		Anwendung.exitprog();
  		}
}
```


----------



## L-ectron-X (12. Mai 2005)

Roar hat gesagt.:
			
		

> @lex: und wenn der benutzer nein auswählt?


Es gibt ja quasi nur eine Aktion des Benutzers, auf welches das Programm reagieren soll. Nämlich dann, wenn er "Ja" klickt und damit das Programm verlassen möchte.
Wenn er "Nein" klickt, wird einfach nur die Methode verlassen, ohne etwas zu tun.


----------



## Roar (12. Mai 2005)

L-ectron-X hat gesagt.:
			
		

> Roar hat gesagt.:
> 
> 
> 
> ...


ja aber wenn der code so in der windowclosing methpde steht wird das programm (oder min das fenster) so doer so geschlossen :?


----------



## Illuvatar (12. Mai 2005)

Ertstes heißt die Klasse Listener*Programm*beenden, zweitens brauchst du nen WindowListener.


----------



## L-ectron-X (12. Mai 2005)

Roar hat gesagt.:
			
		

> ja aber wenn der code so in der windowclosing methpde steht wird das programm (oder min das fenster) so doer so geschlossen


Wenn ich die windowClosing()-Methode leer lasse, passiert gar nichts. 
Beispiel-Code?

```
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MyTestArea extends JFrame {
   public MyTestArea() {
      super("MyTestArea");

      setSize(600, 450);
      setLocationRelativeTo(null);
      setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
      
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            exit();
         }
      });
   }
      
   private void exit() {
      int answer = -1;
      Toolkit.getDefaultToolkit().beep();

      answer = JOptionPane.showConfirmDialog(null,
               "Möchten Sie die Anwendung wirklich beenden?", 
               "Programm beenden", JOptionPane.YES_NO_OPTION);

      switch(answer) {
         case JOptionPane.YES_OPTION:
         System.exit(0);
      }
   }
   
   public static void main(String[] args) {
      new MyTestArea().setVisible(true);
   }
}
```
Es passiert nur das, was ich dort hinein programmiere. So könnte ich genauso gut zwei neue Fenster öffnen, wenn ich eines schließen möchte. :wink:


----------



## Roar (12. Mai 2005)

L-ectron-X hat gesagt.:
			
		

> setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);



jaahhh das gilt halt nicht *incodeeinbau*


----------



## snoop83 (12. Mai 2005)

toll, so gehts ...

thx @ L-ectron-X!

wollt eh als nächstes nach nem beispiel-code fragen ..

komischerweise werden damit auch noch offenen und während der laufzeit erstellte JFrames geschlossen, was vorher nicht der fall war..


----------



## L-ectron-X (12. Mai 2005)

Das liegt am

```
System.exit(0);
```
Diese Anweisung beendet die VM und damit alle noch laufenden Objekte.


----------

