# Blockierender JDialog.



## VipViper2000 (29. Dez 2006)

Hey Leute,

ich hab ein "Problem": Und zwar soll in meiner Anwendung bei Druck auf einen Knopf ein neues Fenster aufploppen in welchem man Koordinaten eingeben kann und diese dann mit OK bestätigt. Jetzt sieht mein Klassendesign im Moment so aus, dass ich aus meinem EventManager (die Klasse fängt alle Events ) eine Instanz der Klasse MyDialog generiere und anzeigen lasse. Jetzt soll aber (im Prinzip nur aus designtechnischen Gründen) die Klasse EventManager keine Klassenvariable haben, die Referenz zum MyDialog ist. Ich hoffe ihr versteht was ich meine. Also im Prinzip will ich genau den Mechanismus von einem JFileChooser haben: Ich kann ihn anzeigen lassen und der Aufruf JFileChooser.showXXXDialog() blockiert so lang, bis ich "Abbrechen" oder "Open" gedrückt hab. Daraufhin kann ich dann die Daten des JFileChoosers abfragen. Aber beim FileChooser wird das blockieren ja durch die show() Methode hervorgerufen, die ja deprecated ist.

Also: Wie löst ihr sowas? Weil das Problem hatte ich schon bei vielen Anwendungen und hab es immer so gelöst, dass der aufploppende Dialog ein Event im EventManager auslöst. Das führt aber halt dazu, dass der Dialog den EventManager kennen muss und umgekehrt, was IMHO designtechnisch nicht so toll ist.

Helft mir mal 

Gruß,
VipViper2000


----------



## Guest (29. Dez 2006)

Das Zauberwort ist "modal". 

Siehe: JDialog(Dialog owner, *boolean modal*)


----------



## VipViper2000 (30. Dez 2006)

Was ein modaler Dialog ist weiß ich sehr wohl. Aber das ist nicht mein Problem. Mir kommt es nicht darauf an, dass erst dieses Fenster geschlossen werden muss, sondern um die Event Verarbeitung beim schließen des Dialogs. Ich möchte praktisch dieses Dialog Fenster aufploppen lassen, der mit einem int-Wert zurückkehrt (genauso wie ein JFileChooser). Das hat den einfachen Vorteil, dass sich die Komponenten nicht gegenseitig kennen müssen. Ist relativ schwer zu beschreiben, aber ich hoffe ihr wisst, was ich meine.


----------



## nocxsville (30. Dez 2006)

Dann mach es doch einfach genaus wie die Chooser.
Also mal schnell dahingeschrieben würde ich das in etwa so machen:


```
public final class ValueChooser extends JDialog {

private ValueChosser() { ... }

public static final int showValueChooser() {
   final ValueChooser vChooser = new ValueChooser ();
   vChooser.setVisible(true);
   
   while(vChooser.isVisible()) {} // evtl. im Thread laufen lassen oder eleganter lösen ;)

   return Integer.parsInt(<WERT_IN_KOMPONENTE>);
}
```

ist zwar jetzt nicht gerade schön, aber soll ja auch nur als Beispiel dienen 

Falls es zu Blockierungen kommt, musst du noch einen Thread rum packen.

Gruß,
nocxsville.


----------



## VipViper2000 (30. Dez 2006)

Hmm joa. Also so wie du es machst meine ich es auf jeden Fall. Aber von endlosen while Schleifen halte ich eigentlich gar nix. Ich muss mir den FileChooser nochmal genauer anschauen. Aber trotzdem danke schonmal.


----------



## Guest (30. Dez 2006)

Vergiss das mit den Threads oder Endlosschleifen. Modal ist modal.
Hier ein Beispiel
	
	
	
	





```
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Frame;
import javax.swing.JDialog;

public class MyDialog extends JDialog
{
   private int result;
   
   private MyDialog(Dialog owner, String title)
   {
      super(owner, title, true);
   }

   private MyDialog(Frame owner, String title)
   {
      super(owner, title, true);
   }
   
   private void setResult(int result)
   {
      this.result = result;
   }
   
   private int getResult()
   {
      return result;
   }
   
   private void initContent()
   {
      // Hier Dialoginhalt/Verhalten etc. initialisieren
   }

   private static int showDialog(Component parent, MyDialog dialog)
   {
      dialog.initContent();
      dialog.setLocationRelativeTo(parent);
      dialog.setVisible(true);
      return dialog.getResult(); 
   }

   public static int showDialog(Dialog owner, String title)
   {
      return showDialog(owner, new MyDialog(owner, title));
   }

   public static int showDialog(Frame owner, String title)
   {
      return showDialog(owner, new MyDialog(owner, title));
   }
   
   public static void main(String[] args)
   {
      int result = MyDialog.showDialog((Frame)null, "BlaBla");
      System.out.println(result);
   }
}
```


----------



## VipViper2000 (30. Dez 2006)

Hey Gast!

Also irgendwie muss ich mich da vertan haben . Das geht ganz genauso wie du sagst. Das liegt aber dann anscheinend daran, dass setVisible() blockierend ist, wenn der Dialog Modal ist, oder? Und sobald ich dann setVisible(false) aufrufe, wird der Lock wieder gelöst. Ich hab irgendwie immer Probleme damit, wenn Dinge so einfach sind .

Also: Vielen Dank dir


----------



## Guest (30. Dez 2006)

VipViper2000 hat gesagt.:
			
		

> Hey Gast!
> 
> Also irgendwie muss ich mich da vertan haben . Das geht ganz genauso wie du sagst. Das liegt aber dann anscheinend daran, dass setVisible() blockierend ist, wenn der Dialog Modal ist, oder? Und sobald ich dann setVisible(false) aufrufe, wird der Lock wieder gelöst. Ich hab irgendwie immer Probleme damit, wenn Dinge so einfach sind .
> 
> Also: Vielen Dank dir


Das mit dem setVisible(false) stimmt schon, aber du musst da aufpassen, in welchem Zustand
der Dialog beendet wird (Klick auf X, was dann?). Insbesondere bei einem Update-Dialog bzw. 
wo das Schliessen an bestimmte Bedingungen geknüpft ist (alle Mussfelder ausgefüllt, eine
Auswahl wurde getroffen etc.). 

Hier die Ergänzung
	
	
	
	





```
...
   private void fireCloseEvent()
   {
      // Das hier kannst du als Reaktion auf OK oder Cancel aufrufen
      dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
   }

   private boolean canClose()
   {
      // Hier eine Prüfung der Daten vornehmen und evtl., wenn nötig, 
      // eine Bestätigung vom Anwender einfordern.
      return JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(
               this, "BlaBla?", "Titel", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE
             );
   }
   
   private static int showDialog(Component parent, final MyDialog dialog)
   {
      // Schliessen zuerst mal nicht erlaubt.
      dialog.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
      dialog.addWindowListener(
        new WindowAdapter() {
           public void windowClosing(WindowEvent e) {
              // Wenn Schliessen zugelassen, dann ...ehmmm, schliessen ;-)
              if(dialog.canClose())
              {
                 dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
              }
           }
        }
      );
      dialog.initContent();
      dialog.pack();
      dialog.setLocationRelativeTo(parent);
      dialog.setVisible(true);
      return dialog.getResult(); 
   }
...
```


----------



## VipViper2000 (30. Dez 2006)

Ja da hast du Recht. Ich hatte das etwas anders gelöst: Ich gebe halt beim Schießen den Int Wert zurück und frage dann im Eventhandler ab, ob alle Daten korrekt eingegeben wurden sind. Aber deine Variante ist natürlich eleganter und ich werd das auch so machen. 

Danke dir nochmal.


----------



## nocxsville (30. Dez 2006)

Noch ein Tipp: Schau dir mal die JFileChooser Klasse an. Ist zwar an manchen Stellen ein wenig verwirrend aber darin findest du deine Antworten 

Gruß,
nocxsville.


----------



## VipViper2000 (30. Dez 2006)

Ja das hab ich ja schon die ganze Zeit gemacht . Und die is teilweise wirklkich verwirrend^^


----------

