# Zwei GUIs - Nach button-Klick soll ein Wert an die andere GUI übergeben werden



## javaKueken (11. Sep 2012)

Bin mir nicht sicher, ob ich den korrekten Titel für diesen Beitrag gewählt habe. Na ja... erstmal egal.
Hier mein Problem:

Ich habe eine GUI in der ich eine oder mehrere Dateien in einer JList markiere, die Namen per renamerules mittels Regex checke, umbenenne und verschiebe in ein anderes Verzeichnis. Falls es keine renamerule gibt, öffnet sich ein weiteres Dialogfenster wo der Dateiname manuell über JTextfields eingegeben werden kann. Am Ende gibt es noch ein JTextfield, dass den neuen Namen dann darstellt. Jetzt will ich, dass dieser neuer Name aus diesem JTextfield übergeben wird an die Methode der anderen Klasse, die das weitere Dialogfenster gestartet hat. Also nochmal: Ich habe ein Dialogfenster in dem ich arbeite. Wenn etwas nicht passt, dann öffnet sich das zweite Dialogfenster, dass mir den neuen Namen in einem JTextfield ermöglicht. Dann soll dieser Name irgendwie gespeichert werden bzw. übergeben werden und das zuletzt geöffnete Dialogfenster soll geschlossen werden. Und ich arbeite weiter im zuerst geöffneten Dialogfenster.
Das Problem ist, dass dieser neue Name aus dem JTextfield erst nach einem Button-Klick übergeben werden soll. Aber der AcctionListener dafür kann ja kein Rügabewert geben, oder?

Hier ein Auszug vom Code für den Button:

```
JButton btnUmbenennen = new JButton("Umbenennen");
		btnUmbenennen.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				getDateinameNeu();
				System.out.println(getDateinameNeu());
				dispose();
			}
		});
```

Und hier versuche ich eine Methode zu schreiben, die das neue Dialogfenster öffnet (was auch funktioniert) und daher auch den neuen Dateinamen erhält:

```
public String manUmbenennen(String dateiname)
	{
		DateiManuellUmbenennen start = new DateiManuellUmbenennen(dateiname);
		start.setVisible(true);

		String dateinameNeu = ...;

		return dateinameNeu;
	}
```


----------



## SlaterB (11. Sep 2012)

String dateinameNeu = start.getDateinameNeu();


----------



## javaKueken (11. Sep 2012)

SlaterB hat gesagt.:


> String dateinameNeu = start.getDateinameNeu();



Ja. Das habe ich mir auch gedacht. Das funktioniert aber nicht. Keine Ahnung warum. Wenn ich das so mache, dann hat dateinameNeu nicht den Wert von start.getDateinameNeu(), sondern "null"
Das ist aber klar, da das JTextfield des neu geöffneten Fensters noch leer ist und erst nach Ausfüllen der anderen Eingabefelder gefüllt wird. Und erst dann soll der Wert des Feldes in dateinameNeu (andere Klasse) geschrieben werden.
Es ist also so, dass das neue Fenster geöffnet wird und direkt danach der Wert (hier leider "null"=leer) in dateinameNeu geschrieben wird, was ich ja nicht möchte. Der Wert soll erst in die Variable rein wenn ich den Button in dem neuen Dialogfenster klicke.
Die Methode aus der ersten GUI-Klasse wird ja sequentiell abgearbeitet, so dass es sie nicht stört ob ein neues Dialogfenster geöffnet wurde und was sich dort tut. Die Methode springt nach dem Öffnes des neuen Dialogfensters einfach zum nächsten Schritt. Jetzt weiß ich nicht wie ich das lösen soll. Ich dachte, dass ich vor dem Hineinschreiben des neuen Wertes in dateinameNeu eine Pause einlegen kann oder so und nicht das nach dem Öffnen des neuen Dialogfensters die Methoode einfach weiter macht.
Ich weiß es einfach nicht und verzweifle seid 2 Tagen.


----------



## Michael... (11. Sep 2012)

Hast Du den Dialog modal gemacht? Dann sollte das eigentlich funktionieren.

Schön ist das dann aber immer noch nicht, da man eigentlich gezielt auf die Aktionen (z.B. Abbrechen) des Anwenders reagieren müsste.


----------



## SlaterB (11. Sep 2012)

ach so, kein modaler Dialog, der würde bei der Zeile setVisible(true); warten bis das andere Fenster zu ist,
ob du in der Richtung was möchtest musst du selber wissen, JOptionPane ist ne einfache Variante
Java: JOptionPane - Simple Dialogs

zu zwei gleichberechtigten Fenstern:
in der Tat ist die Aufrufer-Methode sofort fertig, kann noch nichts machen, dort zu warten würde die GUI blockieren,
es könnte ein Thread gestartet werden der ab und zu nachschaut ob zweiter Dialog fertig, aber unnötig unschön

der erste Dialog könnte sich selber an den zweiten als Parameter übergeben, dort zum Ende hin, im Listener,
ersterDialog.verarbeiteNeuenNamen(..); aufrufen, oder was immer praktisch ist


----------



## mla.rue (11. Sep 2012)

Mh, ich habs bisher immer so gemacht

```
public class GUIfrm2{
     GUIfrm1 frm1;
     String strDateinameNeu;

     public GUIfrm2(ava.awt.Frame parent, boolean modal, GUIfrm1 frmMain) {
        super(parent, modal);
        frm1 = frmMain;

        //die zwei zeilen net zwangsläufig im konstruktor
        strDateinameNeu = frm1.getDateinameNeu();
        //oder
        strDateinameNeu = frm1.txtField.getText();
     }
      //...
}
```


----------



## javaKueken (11. Sep 2012)

Irgendwie kann ich dem ganzen hier nicht folgen.
ich will nochmal so nachfragen... 
Hier nochmal ein Auszug aus der Methode, die für mich arbeiten soll. Meine frage ist als Kommentar eingefügt.


```
if (dateinameNeu == dateiname)
		{
			DateiManuellUmbenennen start = new DateiManuellUmbenennen(dateiname);
			start.setVisible(true);
			
			// an dieser Stelle soll die Methode warten, da zuerst über die zuvor aufgerufene GUI
			// ein Name ermittelt wird und per filewriter in eine txt-Datei geschrieben wird. Nach
			// dem die GUI geschlossen wurde, soll die nächste Anweisung ausgeführt werden: also die
			// Zuweisung - dateinameNeu erhält den neuen Namen als Wert - Aber wie nur wie ???
			
			dateinameNeu = filereader("umbenennung.txt");
		}

		System.out.println("dateinameNeu lautet: " + dateinameNeu);
		return dateinameNeu;
	}
```

Könnt ihr mir hier helfen?


----------



## bERt0r (11. Sep 2012)

Slater hat dir oben einen Link zum JOption Pane gepostet. Das ist genau dafür gemacht worden.


----------



## javaKueken (11. Sep 2012)

bERt0r hat gesagt.:


> Slater hat dir oben einen Link zum JOption Pane gepostet. Das ist genau dafür gemacht worden.



Aber wie kann ich per JOptionPane auf meine GUI (die von mir erstellte mit Eingabefeldern aus denen sich der ganze Name erstellt und in einem Textfeld angezeigt wird) zugreifen und nicht nur auf dieses kleine Dialogfenster wo ich manuell eine Umbenennung vollziehen kann ??? Du meine GUI will ich ein entsprechendes Textmuster bewirken und beeinflussen.


----------



## SlaterB (11. Sep 2012)

Strings nicht mit == vergleichen!
was du mit 'auf meine GUI zugreifen' meinst bleibt unbekannt ohne nachvollziebare Erklärungen,

wenn du im zweiten Fenster nur einen Text eingibst und fertig,
dann könnte "an dieser Stelle soll die Methode warten" direkt umgesetzt werden,

ansonsten, wenn wirklich nötig, habe ich die Alternative auch beschrieben


> zu zwei gleichberechtigten Fenstern:
> in der Tat ist die Aufrufer-Methode sofort fertig, kann noch nichts machen, dort zu warten würde die GUI blockieren,
> es könnte ein Thread gestartet werden der ab und zu nachschaut ob zweiter Dialog fertig, aber unnötig unschön
> 
> ...



also nix mit "an dieser Stelle soll die Methode warten", es geht ja eh erst nach 20 sec weiter wenn eingetippt ist,
da gibt es keinen zwingenden Grund warum das die Methode machen muss,
oder braucht der Aufrufer unbedingt einen Rückgabewert, geht es noch kompliziert weiter?
je dringender, desto eher ein JOptionPane bzw. ein Dialog, den kann man auch komplizierter gestalten, hmm

oder eben wie mich selbst zitiert, Methode beenden, nach 20 sec in neuer Methode weiter


----------



## javaKueken (11. Sep 2012)

SlaterB hat gesagt.:


> Strings nicht mit == vergleichen!
> was du mit 'auf meine GUI zugreifen' meinst bleibt unbekannt ohne nachvollziebare Erklärungen,



Ich habe es jetzt so hingeschrieben: if (dateinameNeu.equalsIgnoreCase(dateiname)) - ist das ok?

Also. Der zukünftige Anwender soll in einem Dialogfenster arbeiten. Wenn ein Dateiname nicht den vorgeschriebenen Textmuster entspricht, soll sich ein weiteres Dialogfenster (das ich erstellt habe) öffnen , in dem der Anwender einige Textfelder ausfüllt und unten im Dialogfenster in einem Feld den vollständigen neuen Dateinamen sehen und per Button bestätigen kann. Hier ist die Besonderheit, dass der neue Dateiname sich an ein vorgegebenes Textmuster hält, in dem ein "+"-Zeichen automatisch an vorgegebenen Stellen hinzugefügt wird. Das Textmuster ist wichtig und man kann leider von den Anwendern nicht erwarten, das sie das Textmuster auswendig lernen. Leider. Deshalb dieses zweite Dialogfenster.
Jetzt habe ich es so geregelt, dass sich das Dialogfenster zum manuellen Umbenennen öffnet und der neuen Dateiname in eine txt-Datei geschrieben wird. Von dort soll die Methode den neuen Dateinamen herauslesen.


----------



## SlaterB (11. Sep 2012)

nun gut, also komplexes zweites Fenster nötig,
ob die Aufrufer-Methode unbedingt was zurückgeben muss, was damit passiert, ist noch nicht geklärt,
wenn einfach nur in ein Textfeld geschrieben wird und nichts weiter passiert bis der Anwender im ersten Fenster irgendeinen Button klickt,
dann wäre das eine entspannte Situation,
wenn aber mitten in komplexer Verarbeitung mit 10 offenen Variablen neue Daten gebraucht werden..

zu allem anderen hast du noch nichts gesagt, 
entweder 20 sec + 2 Methoden,
oder einen modalen Dialog basteln, ist nicht unendlich schwer aber dazu kannst du erstmal lesen

oder noch nicht genannt: 20 sec in der Methode per Schleife warten, wahrscheinlich in einem Thread, sonst wäre die GUI blockiert


----------



## bERt0r (11. Sep 2012)

Du meinst, du machst eine Parameterübergabe indem eine Klasse was in eine Datei schreibt und die ander Klasse das dann aus der Datei rausliest. Noch viel umständlicher gehts glaub ich nicht mehr.

Wieso ist das nicht möglich bei dir?

```
if (dateinameNeu == dateiname)
        {
            DateiManuellUmbenennen start = new DateiManuellUmbenennen(dateiname);
            start.setVisible(true);
            
            String eingabe=JOptionPane.showInputDialog(....);
            while(prüfeTextMuster(eingabe)==false)
            {            
                  eingabe==JOptionPane.showInputDialog(....);
                  //Muster ungültig
             }

            dateinameNeu = filereader("umbenennung.txt");
        }
 
        System.out.println("dateinameNeu lautet: " + dateinameNeu);
        return dateinameNeu;
    }
```


----------



## javaKueken (11. Sep 2012)

SlaterB hat gesagt.:


> nun gut, also komplexes zweites Fenster nötig,
> ob die Aufrufer-Methode unbedingt was zurückgeben muss, was damit passiert, ist noch nicht geklärt,
> wenn einfach nur in ein Textfeld geschrieben wird und nichts weiter passiert bis der Anwender im ersten Fenster irgendeinen Button klickt,
> dann wäre das eine entspannte Situation,
> ...



An diese Methode wird der neue Dateiname übergeben:

```
public void auswaehlenUndVerschieben(JList list, String zielPfad,
			String nameLogdatei, JTextArea nameLoggingfeld)
			throws XPathExpressionException, SAXException,
			ParserConfigurationException
	{

		String dateinameNeu = null;
		int[] selectedIx = list.getSelectedIndices();

		File neu = new File(zielPfad);

		for (int i = 0; i < selectedIx.length; i++)
		{
			File file = (File) list.getModel().getElementAt(selectedIx[i]);
			try
			{
				dateinameNeu = regexMatcher(file.getName());
			} catch (IOException e1)
			{
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			boolean exists = (new File(neu, dateinameNeu)).exists();
			if (exists)
			{
				file.delete();
				String fileDelete = "Die Datei: " + file.getName()
						+ " wurde umbenannt in: " + dateinameNeu
						+ " und wurde im Zielordner erfolgreich überschrieben.";
				try
				{
					saveLog(nameLogdatei, fileDelete);
				} catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(fileDelete);
				logging(nameLoggingfeld, fileDelete);
			}
			else
			{
				boolean success = file.renameTo(new File(neu, dateinameNeu));
				String verschiebenOK = "Die Datei: " + file.getName()
						+ " wurde umbenannt in: " + dateinameNeu
						+ " und wurde nach " + zielPfad
						+ " erfolgreich verschoben.";

				try
				{
					saveLog(nameLogdatei, verschiebenOK);
				} catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(verschiebenOK);
				logging(nameLoggingfeld, verschiebenOK);

				if (!success)
				{
					String verschiebeFehler = "Fehler beim Verschieben der Datei: "
							+ dateinameNeu + " nach: " + zielPfad;
					try
					{
						saveLog(nameLogdatei, verschiebeFehler);
					} catch (IOException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(verschiebeFehler);
					logging(nameLoggingfeld, verschiebeFehler);
				}
			}

		}
	}
```

Dieser neuer Dateiname soll von dieser Methode kommen:

```
// Regex-Matching
	public String regexMatcher(String dateiname)
			throws XPathExpressionException, ParserConfigurationException,
			SAXException, IOException
	{
		String[] regexes = new XMLwork().xmlRenameOld();
		String[] replacement = new XMLwork().xmlRenameNew();

		String dateinameNeu = dateiname;

		for (int i = 0; i < regexes.length; i++)
		{
			Matcher m = Pattern.compile(regexes[i]).matcher(dateiname);

			if (m.find())
			{
				dateinameNeu = m.group().replaceAll(regexes[i], replacement[i]);
			}
		}

		if (dateinameNeu.equalsIgnoreCase(dateiname))
		{
			DateiManuellUmbenennen start = new DateiManuellUmbenennen(dateiname);
			start.setVisible(true);

			// an dieser Stelle soll die Methode warten, da zuerst über das zuvor augerufene
			// Dialogfenster ein Name ermittelt wird und per filewriter in eine txt-Datei
			// geschrieben wird. Nachdem das Dialogfenster geschlossen wurde, soll die nächste
			// Anweisung
			// ausgeführt werden: also >> dateinameNeu = filereader("umbenennung.txt");
			// - Aber wie nur wie ???

			dateinameNeu = filereader("umbenennung.txt");
		}

		// dateinameNeu = JOptionPane.showInputDialog(start, dateinameNeu);

		System.out.println("dateinameNeu lautet: " + dateinameNeu);
		return dateinameNeu;
	}
```

Von 20 sec ist übrigens nicht die Rede gewesen.
Ich habe mir sowas wie wait() und notify() angeschaut, aber ich verstehe es nicht wirklich. Ich würde ja in regexMatcher() in dem if-Zweig irgendwie wait() setzen müssen und aus dem zweiten Dialogfenster *DateiManuellUmbenennen start = new DateiManuellUmbenennen(dateiname);
			start.setVisible(true);*
das notify(), oder? Aber wie?


----------



## javaKueken (11. Sep 2012)

Hier mal ein Beispiel für das Dialogfenster fürs manuelle Umbenennen. Nach Klick auf den Button (siehe roten Pfeil), soll sich das Dialogfenster schliessen und es soll mit dem neuen Dateinamen in der Methode regexMatcher() weitergehen.


----------



## SlaterB (11. Sep 2012)

> Von 20 sec ist übrigens nicht die Rede gewesen.

das ist nur meine Umschreibung um nicht immer wieder die lange Zeit bis der Dialog fertig ist, diese Differenz,
in so komische Worte fassen zu müssen wie in diesem Satz

wait/notify funktionieren nur in einem Thread,
warten könnte der Aufrufer am start-Objekt,

das notify kommt dann in der actionPerformed(), welche das dispose() ausführt, ebenfalls am start-Objekt

grundsätzliche Beispiele zu Threads und Synchronisation aber nachlesen, das ist nichts für 5 Min.


----------

