Statusinformationen realtime ausgeben

Status
Nicht offen für weitere Antworten.

anubisxl

Mitglied
Hi, ich habe ein Programm mit einer GUI, wenn jetzt einzelne Methoden der Programmlogik aufgerufen werden sollen diese Statusinformationen in ein Textfeld schreiben, leider werden die Informationen aber erst wenn das Programm komplett abgelaufen ist in dem Textfeld angezeigt, lässt sich das ändern?
Wenn ich das ganze mit Threads implementieren würde, müsste ich ja quasi jede Methode in eine eigene Klasse packen die dann Runnable implementiert, was etwas aufwendig wäre. Daher dachte ich man kann vielleicht einen eigenen Handler bauen, allerdings müsste ja dann jede Methode ein Ereignis (neueStatusInfoVorhanden) feuern wenn es etwas in das Statusfenster schreiben möchte.

Sind meine Überlegungen soweit schon mal richtig, oder habe ich da was falsch verstanden?

Hat jemand einen Tipp wie ich am besten an die Sache rangehe, vielleicht irgenwelche Tutorials oder so??

Greetz Anubis
 
Richtig liegst du, wenn du sagst, dass du Threads brauchst, dass du für jede Methode eine Runnable Klasse brauchen sollst, ist für mich allerdings nicht nachvollziehbar.
 
Braucht nicht jeder Thread eine Methode run, in der dann der code der Methode steht, die ich ausführen möchte? Demnach müsste ich doch für jede Methode die als Thread laufen soll eine eigene Klasse erstellen, oder was habe ich da jetzt falsch verstanden?

Um meine Problem etwas zu konkretisieren: Ich habe im Prinzip 3 Methoden die sich gegenseitig beeinflussen sollen:

Klick auf Button start das Programm läuft unendlich lange und soll in Echtzeit Informationen in einem Satustextfeld ausgeben

Klick auf Button Stopp, das Programm wird unterbrochen.

Wie macht man das am Besten?
 
in einem Thread können auch mehrere Methoden gleichzeitig stehen
oder eben nur eine Methode, die 10 andere aufruft,

wenn da aber 5 verschiedene Buttons mit eigenen ActionListener hast,
dann ist es korrekt, dass für jede dieser 5 'Aktionen' (nennen wir es mal lieber so) ein Thread zu bauen ist, ja,

eine Alternative wäre anstatt ActionListener eine eigene Klasse RunnableActionListener,
der dafür sorgt, dass die Aktion in der actionPerformed() automatisch nebenläufig ausgeführt wird,
dann hätte man diesen Aufwand nur einmal,

andererseits klingt z.B.
> Klick auf Button Stopp, das Programm wird unterbrochen.
nicht nach etwas, was länger als eine Milliesekunde dauert,
dann braucht es auch keinen Thread

> allerdings müsste ja dann jede Methode ein Ereignis (neueStatusInfoVorhanden) feuern wenn es etwas in das Statusfenster schreiben möchte.

gleich ein Ereignis klingt übertrieben, aber bisschen Aufwand ist jeweils schon, aus einem Thread die GUI zu aktualisieren,

mit einer eigenen Basisklasse RunnableActionListener für alle deartigen Aktionen hättest du wieder evtl. den Vorteil,
Dinge in Hilfsmethoden auszulagern und nicht doppelt implementieren zu müssen,
was immer du auch genau vorhast
 
anubisxl hat gesagt.:
Braucht nicht jeder Thread eine Methode run, in der dann der code der Methode steht, die ich ausführen möchte? Demnach müsste ich doch für jede Methode die als Thread laufen soll eine eigene Klasse erstellen, oder was habe ich da jetzt falsch verstanden?

Um meine Problem etwas zu konkretisieren: Ich habe im Prinzip 3 Methoden die sich gegenseitig beeinflussen sollen:

Klick auf Button start das Programm läuft unendlich lange und soll in Echtzeit Informationen in einem Satustextfeld ausgeben

Klick auf Button Stopp, das Programm wird unterbrochen.

Wie macht man das am Besten?

In dem Beispiel sehe ich nur einen zusätzlichen Thread der irgendwelche Berechnungen durchführt und im Statusfeld ausgibt. Beim Klick auf den Startbutton wird der Thread initialisiert und gestartet und beim Klick auf den Stopp-Button wieder durch interrupt() sauber beendet.

Code:
class MyFrame extends JFrame
{
   private Thread thrRunner;

  public void startThread()
  {
      if (null == thrRunner)
     {
         thrRunner = new MyThread(); 
    }
     thrRunner.start();

  }

  public void stopThread()
  {
      if (null != thrRunner)
     {
         thrRunner.interrupt();
         thrRunner = null;
    }
 }

 private class MyThread extends Thread
 {
     public void run()
    {
        while (!isInterrupted())
       {
          // do something  
      } 
   }
}
}


Wenn der Thread auf die GUI zugreifen soll benutz du aber besser den Kerl hier: http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html
 
Das sieht schon mal sehr gut aus! Danke!
Jetzt hab ich nur ein Problem, ich habe in der auszuführenden Methode öfter ein Thread.sleep() eingebaut wenn ich das deinen code einbaue, führt er den Thread bis in alle Ewigkeit aus, wo liegt denn da mein Denkfehler?

Code:
public static void main(String[] args) {

    startThread();
        try {
            Thread.sleep(20);
        } catch (InterruptedException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

    stopThread();

    }

der Thread:

Code:
public class MyThread extends Thread{

    
    @Override
     public void run()
    {
        while (!isInterrupted())
       {
            System.out.println("not interrupted yet");
            try {
                Thread.sleep(5);
            } catch (InterruptedException ex) {
                Logger.getLogger(MyThread.class.getName()).log(Level.SEVERE, null, ex);
            }

      }
   }

}
 
Vielleicht greifst du auf den falschen Thread zu. Versuch mal das hier:

Code:
while (!isInterrupted())
       {
            System.out.println("not interrupted yet");
            try {
                Thread.currentThread().sleep(5);
            } catch (InterruptedException ex) {
                Logger.getLogger(MyThread.class.getName()).log(Level.SEVERE, null, ex);
            }

      }

Du kannst dir auch mit Thread.getName() den Namen deines Threads ausgeben lassen, dann siehste besser was passiert.
 
ich beobachte das bei mir auch:
Code:
public class Test {

	private static Thread thrRunner;

	public static void main(String[] args) throws Exception {

		startThread();
		try {
			Thread.sleep(200);
		} catch (InterruptedException ex) {
			ex.printStackTrace();
		}
		stopThread();
	}

	public static void startThread() {
		if (null == thrRunner) {
			thrRunner = new MyThread();
		}
		thrRunner.start();
	}

	public static void stopThread() {
		if (null != thrRunner) {
			System.out.println("gleich interrupt");
			thrRunner.interrupt();
			thrRunner = null;
		}
	}

}

class MyThread extends Thread {
	public void run() {
		while (!isInterrupted()) {
			System.out.println("not interrupted yet");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException ex) {
				System.out.println("interrupt: " + isInterrupted());
			}
		}
	}
}

Ausgabe:

not interrupted yet
gleich interrupt
interrupt: false
not interrupted yet
not interrupted yet
not interrupted yet

aber das ist ja ganz egal, ein überflüssiger Status den man leicht selber nachbauen kann,
genausogut also eine neue boolean-Variable definieren und auf true/ false setzen
 
Hm. Das Verhalten ist ... unintuitiv.... Von http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html#interrupt() :


public void interrupt()

Interrupts this thread.

If this thread is blocked in an invocation of ... the ... sleep(long) .... methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
....

If none of the previous conditions hold then this thread's interrupt status will be set.


Allgemein ist es wohl empfehlenswert, das Beenden eines threads NICHT über interrupt/isInterrupted" zu steuern, sondern mit einem eigenen Flag, von dem man genau weiß, wann man es auf welchen Wert setzt. Andernfalls muss man mit einer InterruptedException (wie sie im obigen Beispiel auftritt) richtig umgehen - hier steht ein bißchen was dazu http://www.javaspecialists.co.za/archive/Issue146.html
 
SlaterB hat gesagt.:
aber das ist ja ganz egal, ein überflüssiger Status den man leicht selber nachbauen kann,
genausogut also eine neue boolean-Variable definieren und auf true/ false setzen

Mit der variable läuft es super, werde es so machen.

Danke an Alle für die Tipps!
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben