From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100204.html | 635 +++++++++++++++++++++ 1 file changed, 635 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100204.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100204.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100204.html b/Master/Reference Architectures and Patterns/hjp5/html/k100204.html new file mode 100644 index 0000000..8719ee6 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100204.html @@ -0,0 +1,635 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 31 - GUI-Dialoge +
+
+ + + + +

31.3 Modale Dialoge

+
+ +
+ +

+Modale Dialoge sind solche, die alle Benutzereingaben des Programms +beanspruchen und andere Fenster erst dann wieder zum Zuge kommen lassen, +wenn das Dialogfenster geschlossen wird. Eine wichtige Eigenschaft +modaler Dialoge ist es, dass im Programm der Aufruf zur Anzeige des +Dialogs so lange blockiert, bis der Dialog beendet ist. Auf diese +Weise kann an einer bestimmten Stelle im Programm auf eine Eingabe +gewartet werden und erst dann mit der Bearbeitung fortgefahren werden, +wenn die Eingabe erfolgt ist. + +

+Im AWT des JDK 1.0 gab es einen schwerwiegenden Fehler, durch den +das Erzeugen modaler Dialoge unmöglich gemacht wurde. +Der Fehler hielt sich bis zur Version 1.0.2 und wurde erst mit Erscheinen +des JDK 1.1 behoben. Da viele Anwenderdialoge von Natur aus modalen +Charakter haben, wurde dieser Fehler von vielen als schwerwiegend +angesehen, und die Java-Gemeinde entwickelte eine Reihe von Workarounds, +die aber allesamt nicht voll zufriedenstellen konnten. Glücklicherweise +wurden die Probleme mit dem JDK 1.1 behoben, und wir wollen in diesem +Kapitel aufzeigen, wie modale Dialoge in Java erzeugt werden können. + +

+Ein modaler Dialog muss immer aus der Klasse Dialog +abgeleitet werden. Nur sie bietet die Möglichkeit, an den Konstruktor +einen booleschen Wert zu übergeben, der festlegt, dass die übrigen +Fenster der Anwendung während der Anzeige des Dialogs suspendiert +werden. Dialog +besitzt folgende Konstruktoren: +

+ + + + + +
+ +
+public Dialog(Frame owner)
+
+public Dialog(Frame owner, boolean modal)
+
+public Dialog(Frame owner, String title)
+
+public Dialog(Frame owner, String title, boolean modal)
+
+public Dialog(Dialog owner)
+
+public Dialog(Dialog owner, String title)
+
+public Dialog(Dialog owner, String title, boolean modal)
+
+
+
+java.awt.Dialog
+ +

+Als erstes Argument muss in jedem Fall ein Frame- +oder Dialog-Objekt +als Vaterfenster übergeben werden (bis zur Version 1.1 waren +nur Frame-Objekte +erlaubt). Mit title kann der +Inhalt der Titelzeile vorgegeben werden, und der Parameter modal +entscheidet, ob der Dialog modal dargestellt wird oder nicht. + +

+Dialog +bietet die Methoden isModal +und setModal, +mit denen auf die Modalität des Dialogs zugegriffen werden kann: +

+ + + + + +
+ +
+public boolean isModal()
+
+public void setModal(boolean b)
+
+
+
+java.awt.Dialog
+ +

+Der Rückgabewert von isModal +ist true, +falls der Dialog modal ist. Andernfalls ist er false. +

+ + + + + + + + + + + +
+ +

+Die Methode setModal, +deren Fähigkeit darin besteht, einen bestehenden Dialog zwischen +den Zuständen modal und nicht-modal umzuschalten, ist mit Vorsicht +zu genießen. Unter Windows 95 hat ein Aufruf im JDK 1.1 mitunter +dazu geführt, dass beim Schließen des Fensters die Nachrichtenschleife +des Aufrufers deaktiviert blieb und das Programm sich aufhängte. +Am besten, man entscheidet schon im Konstruktor, ob der Dialog modal +sein soll oder nicht.

+ + + + +
 Warnung 
+
+ +

+Ein zusätzliches Feature der Klasse Dialog +besteht darin, die Veränderbarkeit der Größe eines +Fensters durch den Anwender zu unterbinden: +

+ + + + + +
+ +
+public void setResizable(boolean resizable)
+
+public boolean isResizable()
+
+
+
+java.awt.Dialog
+ +

+Nach einem Aufruf von setResizable +mit false +als Argument kann die Größe des Fensters nicht mehr vom +Anwender verändert werden. Nach einem Aufruf von setResizable(true) +ist dies wieder möglich. Mit isResizable +kann der aktuelle Zustand dieses Schalters abgefragt werden. +

+ + + + + + + + + + + +
+ +

+Auch die Methode setResizable +ist nicht ganz unkritisch, denn sie hat auf einigen UNIX-Systemen +zu Problemen geführt. Sowohl unter SUN Solaris als auch unter +LINUX kam es im JDK 1.1 zu Hängern bei Programmen, die diese +Methode benutzten. Falls sich die nachfolgenden Beispielprogramme +auf Ihrem System nicht so verhalten wie angegeben (typischerweise +wird der Dialog gar nicht erst angezeigt), sollten Sie versuchsweise +den Aufruf von setResizable +auskommentieren.

+ + + + +
 Warnung 
+
+ +

+Das folgende Beispiel demonstriert die Anwendung der Klasse Dialog. +Es zeigt einen Frame, +aus dem per Buttonklick ein modaler Dialog aufgerufen werden kann. +Der Dialog fragt den Anwender, ob die Anwendung beendet werden soll, +und wartet, bis einer der Buttons »Ja« oder »Nein« +gedrückt wurde. In diesem Fall wird ein boolescher Rückgabewert +generiert, der nach dem Schließen des Dialogs an das Vaterfenster +zurückgegeben wird. Falls der Rückgabewert true +(entprechend dem Button »Ja«) ist, wird die Anwendung beendet, +andernfalls läuft sie weiter: + + +

+ + + + + +
+ +
+001 /* Listing3110.java */
+002 
+003 import java.awt.*;
+004 import java.awt.event.*;
+005 
+006 class YesNoDialog
+007 extends Dialog
+008 implements ActionListener
+009 {
+010   boolean result;
+011 
+012   public YesNoDialog(Frame owner, String msg)
+013   {
+014     super(owner, "Ja-/Nein-Auswahl", true);
+015     //Fenster
+016     setBackground(Color.lightGray);
+017     setLayout(new BorderLayout());
+018     setResizable(false); //Hinweis im Text beachten
+019     Point parloc = owner.getLocation();
+020     setLocation(parloc.x + 30, parloc.y + 30);
+021     //Message
+022     add(new Label(msg), BorderLayout.CENTER);
+023     //Buttons
+024     Panel panel = new Panel();
+025     panel.setLayout(new FlowLayout(FlowLayout.CENTER));
+026     Button button = new Button("Ja");
+027     button.addActionListener(this);
+028     panel.add(button);
+029     button = new Button("Nein");
+030     button.addActionListener(this);
+031     panel.add(button);
+032     add(panel, BorderLayout.SOUTH);
+033     pack();
+034   }
+035 
+036   public void actionPerformed(ActionEvent event)
+037   {
+038     result = event.getActionCommand().equals("Ja");
+039     setVisible(false);
+040     dispose();
+041   }
+042 
+043   public boolean getResult()
+044   {
+045     return result;
+046   }
+047 }
+048 
+049 public class Listing3110
+050 extends Frame
+051 implements ActionListener
+052 {
+053   public static void main(String[] args)
+054   {
+055     Listing3110 wnd = new Listing3110();
+056     wnd.setVisible(true);
+057   }
+058 
+059   public Listing3110()
+060   {
+061     super("Modale Dialoge");
+062     setLayout(new FlowLayout());
+063     setBackground(Color.lightGray);
+064     Button button = new Button("Ende");
+065     button.addActionListener(this);
+066     add(button);
+067     setLocation(100,100);
+068     setSize(300,200);
+069     setVisible(true);
+070   }
+071 
+072   public void actionPerformed(ActionEvent event)
+073   {
+074     String cmd = event.getActionCommand();
+075     if (cmd.equals("Ende")) {
+076       YesNoDialog dlg;
+077       dlg = new YesNoDialog(
+078         this,
+079         "Wollen Sie das Programm wirklich beenden?"
+080       );
+081       dlg.setVisible(true);
+082       //Auf das Schließen des Dialogs warten...
+083       if (dlg.getResult()) {
+084         setVisible(false);
+085         dispose();
+086         System.exit(0);
+087       }
+088     }
+089   }
+090 }
+
+
+Listing3110.java
+ +Listing 31.10: Konstruktion modaler Dialoge

+

+ + + + + + + + + +
+ +

+Um den Dialog relativ zur Position seines Vaterfensters anzuzeigen, +wird dessen Position durch Aufruf von getLocation +ermittelt. Der Ursprung des Dialogfensters wird dann 30 Pixel weiter +nach unten bzw. nach rechts gelegt.

+ + + + +
 Hinweis 
+
+ +

+Nach dem Start zeigt das Programm zunächst das in Abbildung 31.14 +dargestellte Fenster an: +

+ + +

+ +

+Abbildung 31.14: Das Vaterfenster für den modalen Dialog

+ +

+Nach dem Klick auf »Ende« wird actionPerformed +aufgerufen und läuft bis zum Aufruf des Dialogs (siehe Abbildung 31.15). +Die Anweisung dlg.setVisible(true); +ruft den Dialog auf und blockiert dann. Sie terminiert erst, wenn +der Dialog durch Drücken eines Buttons beendet wurde. In diesem +Fall wird mit getResult der +Rückgabewert abgefragt und das Programm beendet, wenn dieser +true +ist. Die Methode getResult liefert +den Inhalt der privaten Instanzvariablen result, +die beim Auftreten eines Action-Events durch einen der beiden Buttons +gesetzt wird. Zwar ist das Dialogfenster beim Aufruf von getResult +bereits zerstört, aber die Objektvariable dlg +existiert noch und getResult +kann aufgerufen werden. +

+ + +

+ +

+Abbildung 31.15: Ein einfacher Ja-/Nein-Dialog

+ +

+Bevor wir das Kapitel beenden, wollen wir dieses Programm ein wenig +erweitern und ein weiteres Beispiel für die Anwendung modaler +Dialoge geben. Das folgende Programm implementiert eine Klasse ModalDialog, +die aus Dialog +abgeleitet ist. Mit ihrer Hilfe können modale Dialoge der obigen +Art konstruiert werden, bei denen die Ausstattung mit Buttons variabel +ist und zum Zeitpunkt der Instanzierung festgelegt werden kann: + +

+public ModalDialog(
+   Frame owner,
+   String title,
+   String msg,
+   String buttons
+);
+
+ + +

+Der Konstruktor erwartet neben dem Vater-Frame +drei weitere Parameter, title, +msg und buttons. +In title wird der Inhalt der +Titelzeile übergeben, und msg +spezifiziert den Text innerhalb des Dialogs. Der Parameter buttons +erwartet eine Liste von Button-Bezeichnern, +die zur Festlegung der Anzahl und Beschriftung der Buttons dienen. +Die einzelnen Elemente sind durch Kommata zu trennen und werden innerhalb +des Dialogs mit einem StringTokenizer +zerlegt. Der in getResult gelieferte +Rückgabewert des Dialogs ist - anders als im vorigen Beispiel +- ein String +und entspricht der Beschriftung des zum Schließen verwendeten +Buttons. + +

+ModalDialog enthält einige +statische Methoden, mit denen Dialoge mit einer festen Buttonstruktur +einfach erzeugt werden können. So erzeugt OKButton +lediglich einen Button mit der Beschriftung »OK«, YesNoDialog +zwei Buttons, »Ja« und »Nein«, und YesNoCancelDialog +erzeugt einen Dialog mit drei Buttons, »Ja«, »Nein« +und »Abbruch«. Das folgende Listing zeigt die Klasse ModalDialog +und ein Rahmenprogramm zum Testen: + + +

+ + + + + +
+ +
+001 /* Listing3111.java */
+002 
+003 import java.awt.*;
+004 import java.awt.event.*;
+005 import java.util.*;
+006 
+007 class ModalDialog
+008 extends Dialog
+009 implements ActionListener
+010 {
+011   String result;
+012 
+013   public static String OKDialog(Frame owner, String msg)
+014   {
+015     ModalDialog dlg;
+016     dlg = new ModalDialog(owner,"Nachricht",msg,"OK");
+017     dlg.setVisible(true);
+018     return dlg.getResult();
+019   }
+020 
+021   public static String YesNoDialog(Frame owner, String msg)
+022   {
+023     ModalDialog dlg;
+024     dlg = new ModalDialog(owner,"Frage",msg,"Ja,Nein");
+025     dlg.setVisible(true);
+026     return dlg.getResult();
+027   }
+028 
+029   public static String YesNoCancelDialog(Frame owner,String msg)
+030   {
+031     ModalDialog dlg;
+032     dlg = new ModalDialog(owner,"Frage",msg,"Ja,Nein,Abbruch");
+033     dlg.setVisible(true);
+034     return dlg.getResult();
+035   }
+036 
+037   public ModalDialog(
+038     Frame owner,
+039     String title,
+040     String msg,
+041     String buttons
+042   )
+043   {
+044     super(owner, title, true);
+045     //Fenster
+046     setBackground(Color.lightGray);
+047     setLayout(new BorderLayout());
+048     setResizable(false);
+049     Point parloc = owner.getLocation();
+050     setLocation(parloc.x + 30, parloc.y + 30);
+051     //Message
+052     add(new Label(msg), BorderLayout.CENTER);
+053     //Buttons
+054     Panel panel = new Panel();
+055     panel.setLayout(new FlowLayout(FlowLayout.CENTER));
+056     StringTokenizer strtok = new StringTokenizer(buttons,",");
+057     while (strtok.hasMoreTokens()) {
+058       Button button = new Button(strtok.nextToken());
+059       button.addActionListener(this);
+060       panel.add(button);
+061     }
+062     add(panel, BorderLayout.SOUTH);
+063     pack();
+064   }
+065 
+066   public void actionPerformed(ActionEvent event)
+067   {
+068     result = event.getActionCommand();
+069     setVisible(false);
+070     dispose();
+071   }
+072 
+073   public String getResult()
+074   {
+075     return result;
+076   }
+077 }
+078 
+079 public class Listing3111
+080 extends Frame
+081 implements ActionListener
+082 {
+083   public static void main(String[] args)
+084   {
+085     Listing3111 wnd = new Listing3111();
+086     wnd.setVisible(true);
+087   }
+088 
+089   public Listing3111()
+090   {
+091     super("Drei modale Standarddialoge");
+092     setLayout(new FlowLayout());
+093     setBackground(Color.lightGray);
+094     Button button = new Button("OKDialog");
+095     button.addActionListener(this);
+096     add(button);
+097     button = new Button("YesNoDialog");
+098     button.addActionListener(this);
+099     add(button);
+100     button = new Button("YesNoCancelDialog");
+101     button.addActionListener(this);
+102     add(button);
+103     setLocation(100,100);
+104     setSize(400,200);
+105     setVisible(true);
+106   }
+107 
+108   public void actionPerformed(ActionEvent event)
+109   {
+110     String cmd = event.getActionCommand();
+111     if (cmd.equals("OKDialog")) {
+112       ModalDialog.OKDialog(this,"Dream, dream, dream, ...");
+113     } else if (cmd.equals("YesNoDialog")) {
+114       String ret = ModalDialog.YesNoDialog(
+115         this,
+116         "Programm beenden?"
+117       );
+118       if (ret.equals("Ja")) {
+119         setVisible(false);
+120         dispose();
+121         System.exit(0);
+122       }
+123     } else if (cmd.equals("YesNoCancelDialog")) {
+124       String msg = "Verzeichnis erstellen?";
+125       String ret = ModalDialog.YesNoCancelDialog(this,msg);
+126       ModalDialog.OKDialog(this,"Rückgabe: " + ret);
+127     }
+128   }
+129 }
+
+
+Listing3111.java
+ +Listing 31.11: Drei modale Standarddialoge

+ +

+Die drei Dialoge, die durch Aufrufe von OKDialog, +YesNoDialog und YesNoCancelDialog +generiert werden, sind in den folgenden Abbildungen 31.16 +bis 31.18 dargestellt: +

+ + +

+ +

+Abbildung 31.16: Ein Aufruf von OKDialog

+

+ + +

+ +

+Abbildung 31.17: Ein Aufruf von YesNoDialog

+

+ + +

+ +

+Abbildung 31.18: Ein Aufruf von YesNoCancelDialog

+
+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3