Modaler Dialog ... etwas kompliziert

Hi,

ich bastele gerade eine Oberfläche in Swing.
(mehrere JPanels ineinander verschachtelt, jedes JPanel eine eigene Datei mit eigener Klasse)

Nun habe ich mehrere Probleme:

  1. In einem dieser Panels (3. oder 4. Ebene) möchte ich einen Button erstellen, der einen modalen Dialog aufruft, der das gesamte JFrame sperrt.
    Wie komme ich auf mein JFrame, bzw. die nötige Klasse?
    Oder muß ich dieses JPanel und den Button als interne Klasse einbinden?

  2. Der Dialog soll mit einem „Bitte Warten“ - Label dargestellt werden, da dann eine längere Operation losläuft (im Hintergrund externes Programm, durch eine Batch-Datei gestartet)
    Wenn das Ding fertig ist, soll dann der Dialog eine neue Maske darstellen, welche u.a. Ergebnisse der externen Operation darstellt.
    Ich habe mir gedacht, ich schreibe ein „warte-JPanel“, rufe dann die externe Anwendung auf (mit wait warte ich, bis sie durchgelaufen ist) und dann generiere ich ein neues Panel, und schmeiße dann das „warte-JPanel“ mittels remove raus, und hänge das neue rein.

Hat jemand ne bessere Idee?

Besten Dank

Winni

Moin

  1. In einem dieser Panels (3. oder 4. Ebene) möchte ich einen
    Button erstellen, der einen modalen Dialog aufruft, der das
    gesamte JFrame sperrt.

JDialog, modular…

Wie komme ich auf mein JFrame, bzw. die nötige Klasse?

Du kannst doch beim erzeugen einen Pointer auf das JFrame übergeben… oder dich per getParent bis zur ContentPane hocharbeiten. Ich seh das Problem immer noch nicht.

Oder muß ich dieses JPanel und den Button als interne
Klasse einbinden?

Nein.

  1. Der Dialog soll mit einem „Bitte Warten“ - Label
    dargestellt werden, da dann eine längere Operation losläuft
    (im Hintergrund externes Programm, durch eine Batch-Datei
    gestartet)

Runtime.exec kenns du ?

Wenn das Ding fertig ist, soll dann der Dialog eine neue Maske
darstellen, welche u.a. Ergebnisse der externen Operation
darstellt.

Theo geht das was du vorhast, aber: es ist schneller, sauberer und vor allem einfacherer den Dialog zu schliessen und einen neuen anzuzeigen. In Swing Elemente auszutauschen ohne das Layout oder die event-Manager zu zerstören ist …ähmmm… komplex.

Hat jemand ne bessere Idee?

Denk an das Problem mit dem AWT-Swing-Thread. NIEMALA in einer event-Methode eine lang laufende Operation aufrufen, immer nut Threads starteh.

cu

Servus,

Moin

  1. In einem dieser Panels (3. oder 4. Ebene) möchte ich einen
    Button erstellen, der einen modalen Dialog aufruft, der das
    gesamte JFrame sperrt.

JDialog, modular…

Klar JDialog, die Grund-Modellierung geht auch gut mit dem Visual-Editor. (Eclipse)

Wie komme ich auf mein JFrame, bzw. die nötige Klasse?

Du kannst doch beim erzeugen einen Pointer auf das JFrame
übergeben… oder dich per getParent bis zur ContentPane
hocharbeiten. Ich seh das Problem immer noch nicht.

Also gehe ich über Component.getParent(), bis ich ein JFrame finde?

Oder muß ich dieses JPanel und den Button als interne
Klasse einbinden?

Nein.

Ok, wenn ich mit getParent weiterkäme…

  1. Der Dialog soll mit einem „Bitte Warten“ - Label
    dargestellt werden, da dann eine längere Operation losläuft
    (im Hintergrund externes Programm, durch eine Batch-Datei
    gestartet)

Runtime.exec kenns du ?

Ja klar, damit wollte ich das ja machen…
und dann eben wait, bis es fertig ist.

Wenn das Ding fertig ist, soll dann der Dialog eine neue Maske
darstellen, welche u.a. Ergebnisse der externen Operation
darstellt.

Theo geht das was du vorhast, aber: es ist schneller, sauberer
und vor allem einfacherer den Dialog zu schliessen und einen
neuen anzuzeigen. In Swing Elemente auszutauschen ohne das
Layout oder die event-Manager zu zerstören ist …ähmmm…
komplex.

Wie schließe ich denn den Dialog?

Hat jemand ne bessere Idee?

Denk an das Problem mit dem AWT-Swing-Thread. NIEMALA in einer
event-Methode eine lang laufende Operation aufrufen, immer nut
Threads starteh.

Wie meinst du das denn?
Ich MUSZ (so ist die Anforderung) während der externen Berechnung (Batch-Job stößt eine Exe an, kann u.U. auch länger als 5 sec. dauern) die gesamte Anwendung sperren.

cu

Gruß
Winni

PS: Früher haben die das mittels Prozeß-Kommunikation unter Unix gemacht, nun darf ich das unter Windows nachbauen. (es sind 4-5 Programme, die sich gegenseitig irgendwie aufrufen)

Moin

Du kannst doch beim erzeugen einen Pointer auf das JFrame
übergeben… oder dich per getParent bis zur ContentPane
hocharbeiten. Ich seh das Problem immer noch nicht.

Also gehe ich über Component.getParent(), bis ich ein JFrame
finde?

nein, du wirst kein JFrame finden, nur eine ContentPane. Von der aus dann das JFrame bestimmen.

Wie schließe ich denn den Dialog?

JDialog.close();

Wie meinst du das denn?

Wenn du in einer event-Methode (einer Methode die durch einen klick oder Menü vom User angestossen wird) per wait() oder durch eine andere lange laufende Methode den Thread festhälts bleibt die GUI stehen. D.h. dann kann man nichts mehr anklicken, gar nichts reagiert und es wird auch nichts mehr neu gezeichnent. Man MUSS also einen Thread starten um was längeres zu erledigen.

Ich MUSZ (so ist die Anforderung) während der externen
Berechnung (Batch-Job stößt eine Exe an, kann u.U. auch länger
als 5 sec. dauern) die gesamte Anwendung sperren.

Das erledigt schon das JDialog: Modulare JDialogs blockieren das JFrame bis sie wieder geschlossen werden.

PS: Früher haben die das mittels Prozeß-Kommunikation unter
Unix gemacht, nun darf ich das unter Windows nachbauen. (es
sind 4-5 Programme, die sich gegenseitig irgendwie aufrufen)

… viel Spass. Unter Unix ist das ja noch einigermassen organisiert, aber unter windows… *graus*.

Unter Windows musst du auch den OutputStream des gestarten „Process“ auslesen. Tut man das nicht so bleibt der Process irgendwann (nach ±32 Zeichen) stehen.

Wenn du Codebeispiele brauchts: poste nochmal.

cu

Moin

Du kannst doch beim erzeugen einen Pointer auf das JFrame
übergeben… oder dich per getParent bis zur ContentPane
hocharbeiten. Ich seh das Problem immer noch nicht.

Also gehe ich über Component.getParent(), bis ich ein JFrame
finde?

nein, du wirst kein JFrame finden, nur eine ContentPane. Von
der aus dann das JFrame bestimmen.

Klaro, ich hangle mich mittels (Component).getParent() solange nach oben, bis ich das Frame gefunden habe. (Schleife)

Wie schließe ich denn den Dialog?

JDialog.close();

THX, ist mir irgendwo in den Javadocs nicht aufgefallen.

Wie meinst du das denn?

Wenn du in einer event-Methode (einer Methode die durch einen
klick oder Menü vom User angestossen wird) per wait() oder
durch eine andere lange laufende Methode den Thread festhälts
bleibt die GUI stehen. D.h. dann kann man nichts mehr
anklicken, gar nichts reagiert und es wird auch nichts mehr
neu gezeichnent. Man MUSS also einen Thread starten um was
längeres zu erledigen.

Also ich dachte, ich habe in meiner GUI einen Button, der einen Dialog öffnet.
Dieser Dialog
stellt sich als „bitte warten“-Dialog vor
Startet dann die externe SW mittels Runtime.exec() und bleibt solange „stehen“ mittels wait()
Wenn der externe Prozeß fertig ist, wird der Dialog „umgebaut“ (neues Panel, welches eine TextArea hat für ne Ausgabe der Fehlermeldungen, die in einer anderen Textdatei stehen und OK-Button zum Schließen)

Ich MUSZ (so ist die Anforderung) während der externen
Berechnung (Batch-Job stößt eine Exe an, kann u.U. auch länger
als 5 sec. dauern) die gesamte Anwendung sperren.

Das erledigt schon das JDialog: Modulare JDialogs blockieren
das JFrame bis sie wieder geschlossen werden.

Ja klar, und wie kann ich verhindern, daß der Dialog geschlossen werden kann?
(ich will aich das kleine Windows-X irgendwie abfangen)

PS: Früher haben die das mittels Prozeß-Kommunikation unter
Unix gemacht, nun darf ich das unter Windows nachbauen. (es
sind 4-5 Programme, die sich gegenseitig irgendwie aufrufen)

… viel Spass. Unter Unix ist das ja noch einigermassen
organisiert, aber unter windows… *graus*.

Naja, ich habe mir auch nicht Java ausgesucht, muß es aber hinbiegen.

Unter Windows musst du auch den OutputStream des gestarten
„Process“ auslesen. Tut man das nicht so bleibt der Process
irgendwann (nach ±32 Zeichen) stehen.

OK, also da habe ich schon die Tests gemacht mit den einzelnen Streams, das läuft im Prinzip.
(der Job gibt normalerweise nix aus sondern liest nur eine Textdatei ein, verarbeiten die und gibt die wieder aus)

Wenn du Codebeispiele brauchts: poste nochmal.

cu

Gerne…

Schickst Du sie mir gleich an meine Mail-Addy?

Besten Dank

Winni

Moin

nein, du wirst kein JFrame finden, nur eine ContentPane. Von
der aus dann das JFrame bestimmen.

Klaro, ich hangle mich mittels (Component).getParent() solange
nach oben, bis ich das Frame gefunden habe. (Schleife)

Verdammt, hast Recht. JFrames sind ja auch Container. (Man muss Components ja immer über getContentPane().add(…) einfügen, und da war ich mir nicht sicher ob man bis zum JFrame kommt)

Wie schließe ich denn den Dialog?

JDialog.close();

THX, ist mir irgendwo in den Javadocs nicht aufgefallen.

Sorry, ich meinte hide()… Es gibt Tage da sollte man einfach nicht aufstehen.

Also ich dachte, ich habe in meiner GUI einen Button, der einen
Dialog öffnet.
Dieser Dialog
stellt sich als „bitte warten“-Dialog vor
Startet dann die externe SW mittels Runtime.exec() und bleibt
solange „stehen“ mittels wait()

Das ist eine klare Vorgabe.

Wenn der externe Prozeß fertig ist, wird der Dialog „umgebaut“
(neues Panel, welches eine TextArea hat für ne Ausgabe der
Fehlermeldungen, die in einer anderen Textdatei stehen und
OK-Button zum Schließen)

Das würd ich durch eine 2. Dialog lösen (erster weg, zweiten anzeigen) Aber das Detail überlass ich dir…

Ja klar, und wie kann ich verhindern, daß der Dialog geschlossen
werden kann?
(ich will aich das kleine Windows-X irgendwie abfangen)

setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);

Dann sollte gar nichts mehr passieren (bei Exoten wie z.B. twn und fvwm unter Linux für ich mir nicht so sicher, ber unter windows wirkt das Wunder…)

Schickst Du sie mir gleich an meine Mail-Addy?

Ich post sie hier, sind eh nur Bruchstücke und nicht getestet:

public class MAIN{

JDialog waiting;

 /\*\* Die Event-Methode \*/
 public void actionPerformed (ActionEvent A){
 Frame F = getMyParent ();
 waiting = new JDialog(F,true);
 waiting.setDefaultCloseOperation(JDialog.DO\_NOTHING\_ON\_CLOSE);

 ... init JDialog ....
 //Hier kommt eine JProgressBar mit setIndeterminate(true) immer gut ...

 Thread runner = new Runner(this);
 runner.start();
 waiting.show(); // \* Hier bleibt er stehen bis der Dialog wieder geschlossen wurde.
 }

 public void finishedProcess (String errorMessages){
 JDialog derNeueDialog = new DeinDialog(errorMessages);
 waiting.hide(); //Wenn das aufgerufen wird geht der Thread bei \* erst weiter.
 derNeueDialog.show();
 }
}

public class Runner extends Thread {

 MAIN m;

 public Runner (MAIN M){
 m = M;
 }

 public void run (){
 try {
 Process P = Runtime.getRuntime.exec (WasAuchImmer);
 new Reader (P.getOutputStream()).start(); //Wenn du die 2 Threads auslässt bleibt der Process irgendwann wegen vollen Buffer stehen.
 new Reader (P.getErrorStream()).start();
 P.waitFor();
 m.finishedProcess ("no errors");
 } catch (Exception E){
 m.finishedProcess (E.toString());
 }
 }
}

Und wenn du das ganze vorzeitig abbrechen willst: P.destroy(); m.finishedProcess („Abbruch“); dann aber nicht vergessen.

cu