JTextarea Ausgabe ist verzögert

ramotzkie

Grünschnabel
Hi,
ich hab folgendes Problem.
Ich möchte, dass der User eine .exe Datei auswählt, und sobald er auf Start drückt wird diese beliebig oft(auswahl per Jspinner) hintereinander gestartet und wieder beendet, in einem Abstand von 20 Sekunden.
Um das zu protokollieren soll der User in einer JTextarea folgende Ausgabe erhalten:
programm.exe 1 ist gestartet
programm.exe 1 ist beendet
...
usw.
Folgendes Problem tritt nun auf.
Das Programm bleibt hängen, sobald ich auf "Start" drücke, startet und beendet die .exe und erst danach wird der Text ausgegeben.

Code:
JSpinner spinner;
JButton choose, start;
JTextArea log;
JFileChooser fc;

public void actionPerformed(ActionEvent e) {

        
        if (e.getSource() == choose)								  //Wenn der Button choose gedrückt wurde für .exe-Auswahl
        {
            int returnVal = fc.showOpenDialog(Programm.this);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                log.append(file.getName() + " ausgewählt\n");
            } else {
            	log.append("Abbruch durch Benutzer\n");
            }
        }
        else if(e.getSource() == start)									//wenn Start gedrückt wurde
        {
        	File file = fc.getSelectedFile();
        	try {
        		int amount = ((Integer) spinner.getValue());
                        log.append("Programm wird " + amount + " mal gestartet!\n");
				startProgramm(file.getName(), file.getPath(), amount);
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
        }
    }

Code:
public void startProgramm(String name, String path, int loops) throws Exception
	{
		for(int i=1; i<=loops;i++)
		{
	        ProcessBuilder pb = new ProcessBuilder(path);
	        Process process = pb.start();
                log.append(name + " " + i + " ist gestartet\n");
	        Thread.sleep(20000);
	        process.destroy();
	        log.append(name + " " + i + " ist beendet\n");
		}
		log.append("Ausführung beendet!\n");
	}

Das Programm gibt keinen Fehler aus, führt auch alles aus, lediglich die Verzögerung in der Anzeige der JTextarea stört mich.
Ich hoffe mein Problem ist klar geworden und es gibt jemanden, der in der Lage ist mir zu helfen.

Danke fürs Lesen
mfg
ramotzkie
 
Du blockierst durch dein Thread.sleep(20000) den Main-Thread für 20 Sekunden. Der Main-Thread kann also nicht in deine JTextArea schreiben und diese neu zeichnen usw. weil er blockiert. Lagere also das starten und stoppen der Anwendungen in einen eigenen Thread aus, dann sllte das ganze funktionieren.

gruß
sony2
 
Hey Sony2
erstmal vielen vielen dank für deine schnelle Antwort.

Ich habe versucht das umzusetzen, allerdings funktioniert es nicht.
Da ich noch NIE vorher mit Threads gearbeitet habe, weiß ich allerdings auch nicht ob ich evtl. einen Fehler gemacht habe.
Wäre sehr nett, wenn du nochmal drüber schauen könntest.

Hier die beiden Threads, einmal für die Ausgabe, das andere mal für das Ausführen
Code:
class ExecuteThread extends Thread
	{
		Process process;
		public void run()
		{
			
		}		
		public void pzstart() throws Exception
		{
			ProcessBuilder pb = new ProcessBuilder(textfield.getText());
	        process = pb.start();
		}
		public void pzend() throws Exception
		{
			process.destroy();
		}
		public void pause() throws Exception
		{
			ExecuteThread.sleep(10000);
		}
	}
	
	class AusgabeThread extends Thread
	{
		public void run()
		{
			
		}	
		public void starter(int i)
		{
			log.append(i + " ist gestartet\n");
		}
		public void ender(int i)
		{
			log.append(i + " ist beendet\n");
		}
	}

Hier werden die Threads erstellt und ausgeführt
Code:
ExecuteThread threadStart = new ExecuteThread();
		threadStart.start();
		AusgabeThread threadAusgabe = new AusgabeThread();
		threadAusgabe.start();
		for(int i=1; i<=loops;i++)
		{
	        threadStart.pzstart();
	        threadAusgabe.starter(i);
	        threadStart.pause();
	        threadStart.pzend();
	        threadAusgabe.ender(i);
		}

vergebt mir bitte mein unwissen, ist das erste mal, dass ich etwas mit threads gemacht habe^^
mfg
ramotzkie
 
Bei der Arbeit mit Threads musst du beachten das die public void run()-Methode die wichtigste Methode ist. Diese Methode wird nach dem erstellen des Threads gestartet und stellt dann den eigentlichen Thread dar.

Thread Klasse:
Code:
public class ProcessThread extends Thread
{
 private String name;
 private String path;
 private int loops;
 // Konstruktor
 public ProcessThread(String name, String path, int loops)
 {
  this.name = name;
  this.path = path;
  this.loops = loops;
 }
 
 // die run Methode
 public void run()
 {
  for(int i=1; i<=loops;i++)
  {
   ProcessBuilder pb = new ProcessBuilder(path);
   Process process = pb.start();
   log.append(name + " " + i + " ist gestartet\n");
   Thread.sleep(20000);
   process.destroy();
   log.append(name + " " + i + " ist beendet\n");
  }

  log.append("Ausführung beendet!\n");
 }
}

Aufruf in der Applikation:
Code:
ProcessThread pt = new ProcessThread(file.getName(), file.getPath(), amount);
pt.start();

...hab den Code jetzt nicht ausprobiert, aber grob sollte er so funktionieren. Wenn du die Prozessaufrufe auslagerst solltest du eigentlich auch keinen eigenen Thread für die Anzeige in der GUI brauchen. Durch den Aufruf von pt.start() wird dann die run Methode der Threadklasse gerufen. Ist diese beendet so ist dann auch der Thread beendet.

Hoffe ich konnte helfen

gruß
sony2
 
hey,
also es hat funktioniert!
super danke schön
nebenbei hab ich auch noch verstanden wie man mit threads umgeht
besser geht es nicht :)

danke schöön
 

Neue Beiträge

Zurück