Gui und Aufgaben Threads

Sunchezz

Bekanntes Mitglied
Hallo Leuts,

in meiner kleinen Software soll es eine kleine JProgressBar geben und ich habe mir gedacht, da ich das noch nie so wirklich zum laufen bekommen habe, aber schon viel drüber gelesen, Konstruiere ich meine Software von anfang an so das sie über zwei Threads läuft.
Habe hier im Forum gelesen das das generell sowieso ganz sinnvoll sein soll die GUI und die logischen aufgaben in zwei verschiedenen Threads zu trennen.
Nun für mich die Preisfrage, wie geht das?

Ich habe es bisher so versucht:
Ich habe eine Main-Klasse, in der werden zwei Objekte erstellt, einmal das GUI-Frame, und dann meine Controller-Klasse, in der wiederum alle anderen Teilaufgaben und klassen initialisiert werden.

MAIN-Klasse:
Code:
...
SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          programm = new Programm("Test");
          programm.setVisible(false);
          System.out.println(Thread.currentThread().toString());
        }
      });

      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          controller.init();
          programm.setVisible(true);
          System.out.println(Thread.currentThread().toString());
        }
      });
...

allerdings tut sich hier herzlich wenig, und die ProgressBar verrichtet ihre arbeit auch nur auf die gute alte Art: Gui einfrieren und dann auf volle 100%

Code:
  private Thread guiThread = new Thread() {
    public void run() {
      programm = new Programm("Test");
    }
  }
  private Thread logicThread = new Thread() {
    public void run() {
      controller = new MainController();
    }
  }
Auch dieser Versuch führte nicht zum gewünschten erfolg!

Wäre euch dankbar für jede Hilfe!

Sunny
 

Michael...

Top Contributor
Habe hier im Forum gelesen das das generell sowieso ganz sinnvoll sein soll die GUI und die logischen aufgaben in zwei verschiedenen Threads zu trennen.
Es ist sinnvoll langwierige Aufgaben bzw. blockierende Aufgaben in einem separaten Thread abzuarbeiten.
Versuchst Du generell View und Controller in unterschiedlichen Threads zu initialisieren? Das macht nicht unbedingt Sinn.

Zu Code 1 Runnables mit SwingUtilities.invoke... aufgerufen laufen im EDT also laufen die vermeitlichen zwei Abläufe im selben Thread
Zu Code 1 unabhängig davon, ob das Sinn macht (wie) werden die Thread den gestartet?

Hier noch ein Beispiel zum Thema Thread:
Java:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class SimpleThreadDemo extends  JFrame {
	private JLabel label;
	
	public SimpleThreadDemo () {
		label = new JLabel("0", JLabel.CENTER);
		this.getContentPane().add(label);
		new Thread(new MySpecialTask()).start();
	}
	
	
	class MySpecialTask implements Runnable {
		private int i;
		public void run() {
			i=0;
			// folgender Prozess läuft unendlich lange 
			// und aktualiert dabei ca. jede Sekunde die GUI 
			while (true) {   
				try {
					Thread.sleep(1000);				
					label.setText("" + ++i);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				JFrame frame = new SimpleThreadDemo();
				frame.setBounds(0, 0, 150, 100);
				frame.setLocationRelativeTo(null);
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setVisible(true);
			}
		});
	}
}
 

tagedieb

Top Contributor
Ich empfehle dir mal diese Seite zu lesen. Ansonsten wirst du klaeglich scheitern.

GUIs are singlethreaded

Das heisst, dass immer nur EIN Thread auf Swing Komponenten zugreifen duerfen (die ist der Event-Thread, welcher vom Swing Framework gestarted wird). Mit SwingUtilities.invokeLater(...) kannst du Aufgaben an den Event-Thread uebertragen. Dieser wird deine Tasks sequenziel abarbeiten. Also wenn du hier langwierige Aufgaben oder schlimmer noch endlos Schleifen uebergibst blockierst du das ganze GUI.

Ja, ich aergere mich auch immer ueber schlecht implementiere Applikationen in welchen der 'Abbrechen ' Knopf nicht funktioniert und das ganze GUI einfriert. Das hat wohl schon jeder erlebt und das ist der Grund dafuer. ;-)
 

Sunchezz

Bekanntes Mitglied
@Michael...
Die Threads werden normal mit "start()" gestartet...

Und ja, ich dachte das wäre am sinnvollsten, wenn ich von vorne rein die "aufgaben-klassen" und das GUI in zwei verschiedene Threads packe, ich dachte dann würden die anderen initalisierten aufgaben-Objekte auch gleich in dem neuen Thread erzeugt?!

Oder muss ich jede einzelne logik-methode die nix mit der gui zu tun hat in nem neuen Thread packen?
und vor allem, manche von den logik sachen sollen dann ja im nachhinein noch das GUI updaten und mit neuen Daten versorgen. wie läuft das?

hab mir jetzt beide Seiten angeschaut, und größtenteils den Sinn verstanden, offenbar aber noch nicht ausreichend, denn ich weiß nich wie mir das weiterhilft!
Obwohl sich für mich der Swingworker am besten angehört hat xD
 

Sunchezz

Bekanntes Mitglied
So, ich kann ja jetzt einfach mal nen Konkretes Beispiel posten:

Das ist meine Methode:
Code:
public void checkeAlleProxys() {
    int listLenght = Start.controller.getSpeicher().getProxys().size();
    Start.programm.getProgressBar().setMinimum(0);
    Start.programm.getProgressBar().setMaximum(listLenght);
    for (int i = 0; i < listLenght; i++) {
      System.out.println("\nProxy " + i);
      if (this.checkProxy(Start.controller.getSpeicher().getProxys().get(i)) == true) {
        Start.controller.getSpeicher().getProxys().get(i).setIstErreichbar(true);
        Start.controller.getSpeicher().getProxys().get(i).setNutzbar(true);
      } else {
        Start.controller.getSpeicher().getProxys().get(i).setIstErreichbar(false);
        Start.controller.getSpeicher().getProxys().get(i).setNutzbar(false);
      }
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          Start.controller.updateProgressBar(1);
        }
      });
    }
  }

Und dieses Teil hier hab ich irgendwo als Beispiel runtergeladen:

Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ProgressBarExample extends JPanel {

  JProgressBar pbar;
  static final int MY_MINIMUM=0;
  static final int MY_MAXIMUM=300;

  public ProgressBarExample() {
     pbar = new JProgressBar();
     pbar.setMinimum(MY_MINIMUM);
     pbar.setMaximum(MY_MAXIMUM);
     add(pbar);
  }

  public void updateBar(int newValue) {
    pbar.setValue(newValue);
  }

  public static void main(String args[]) {
     try {
       javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
     }catch (Exception e) {

     }

     final ProgressBarExample it = new ProgressBarExample();

     JFrame frame = new JFrame("Progress Bar Example");
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     frame.setContentPane(it);
     frame.pack();      // angucken
     frame.setVisible(true);

     for (int i = MY_MINIMUM; i <= MY_MAXIMUM; i++) {
       final int percent=i;
       try {
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
               it.updateBar(percent);
             }
         });
         java.lang.Thread.sleep(10);
       } catch (InterruptedException e) {;}
     }
  }
}
Das Funktioniert, wieso meins nicht?
meiner Meinung nach ist es genau das gleiche...
außer das in meiner Methode "Thread.sleep" durch die "Arbeit" ersetzt wurde die ja simuliert werden sollte.

also was nun?
Doch auf Threads umsteigen?

Swingworker hat im übrigen auch nicht so funktioniert wie ich wollte...
Habs heute auch noch nicht so lange versucht, werd ich wohl noch mal machen müssen!

Ich steig einfach nicht dahinter wie das funktioniert!
 

tfa

Top Contributor
Das Funktioniert, wieso meins nicht?
Deine Aktion läuft im Event-Dispatch-Thread ab und blockiert ihn. Dadurch wird der Progressbar nicht neu gezeichnet.
Das Beispiel läuft im Hauptthread. Das ist der Unterschied.

Swingworker hat im übrigen auch nicht so funktioniert wie ich wollte...
Habs heute auch noch nicht so lange versucht, werd ich wohl noch mal machen müssen!
Das solltest du.
 

Sunchezz

Bekanntes Mitglied
Wo änder ich das denn dann??
bzw. wo steht das im Beispiel die Anweisung für den Hauptthread?
Oder anderesrum, wo steht bei meinem das es der EDT ist?
 

tfa

Top Contributor
Die main-Methode startet im Main-Thread - ganz einfach.
Du rufst deine Arbeitsmethode wahrscheinlich von einem ActionListener oder sowas auf, d.h. auf ein Event von der GUI hin. Und die werden nunmal im EDT erzeugt. Im EDT sollte man nur Dinge tun, die höchstens ein paar Millisekunden dauern können. Dann hat man mit einfrierenden GUIs keine Probleme.
 

Sunchezz

Bekanntes Mitglied
Alles klar... verstanden und abgespeichert =)

Und was kann ich nun genau tun?
was würdet ihr mir denn empfehlen?

Ich habe so einige sehr lang dauernde (teilweise 10 min) Methoden die über Buttons gestartet werden, wie kann ich die nun mit einer ProgressBar koppeln, und das einfrieren des GUI verhindern?
Wie gesagt, ich habe eine einzige Klasse für das GUI, und viele kleine andere die angesprochen werden sollen.

Was kann ich da nun machen?

Weiß das ich mich grad irgendwie bescheuert anstelle, aber das mit den ganzen Threads, Runnable und SwingWorker ergibt für mich keinen Sinn!
Verstehn tu ich den Mist ja, aber ich bekomme es einfach nicht hin das vernünftig in mein Programm zu übertragen.
 

Michael...

Top Contributor
Innerhalb der actionPerformed startest Du einen neuen Thread in dem die lange dauernde Methode aufgerufen/abgearbeitet wird. Nach einzelnen Bearbeitungsschritten oder Schleifendurchgängen in dieser Methode wird der neue Status an die ProgressBar übermittelt.
Hinweis: Wenn man innerhalb nebenläufiger Threads auf GUI Komponenten zugreift, empfiehlt es sich (abhängig von den Methoden) dies wiederum innerhalb eines SwingUtilities.invokeLater... Konstrukts zu tun.
 

Sunchezz

Bekanntes Mitglied
danke für alle antworten... das letzte war gut und hat mich weiter gebracht...!

Ich finde zwar das das scheiße viel arbeit insgesamt ist aber nun gut xD
 

Sunchezz

Bekanntes Mitglied
An sich ist das ursprüngliche Problem geklärt, jetzt läuft in der Hinsicht alles wie es soll...!

Nur, wenn die Software beendet wird bevor der Thread abgearbeitet ist, erledigt er seine Aufgabe trotzdem noch bis zum Ende obwohl die Software mehr oder weniger "tot" ist.
Wie unterbinde ich das bitte?
Habe gelesen das, da ja alle gängigen Methoden deprecated sind, nur eine null-referenz einen Thread wirksam schliesst.
Daher dachte ich mir das ja theoretisch ein windowListener mit windowClosed() und der null-referenz eigentlich reichen sollte, tuts aber nicht.

Ich könnte ja einfach das Problem umgehen indem ich das Beenden der Software vor fertigstellung des Threads unterbinde, aber das fühlt sich für mich wie schummeln an ^^

wie händelt ihr das normaler weise?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L Swing Schulprojekt GUI mathematische aufgaben AWT, Swing, JavaFX & SWT 16
GUI-Programmer Swing - Aufgaben AWT, Swing, JavaFX & SWT 10
frager2345 Threads -> Ereignisbehandlung AWT, Swing, JavaFX & SWT 2
N jFrame löscht am Ende des Threads alles AWT, Swing, JavaFX & SWT 2
J GUI Ausgaben aus Threads AWT, Swing, JavaFX & SWT 13
A Swing ProgressBar über 2 parallel laufende Threads AWT, Swing, JavaFX & SWT 2
N JavaFX Logging des JavaFX Application Threads mit Log4J AWT, Swing, JavaFX & SWT 3
U JAVAFX observer und threads AWT, Swing, JavaFX & SWT 1
J Textlabel verändern mit parallelen Threads AWT, Swing, JavaFX & SWT 7
Sugan Inhalte mit Threads ändern -> java.lang.IllegalStateException AWT, Swing, JavaFX & SWT 6
R Straßenkreuzung - Ampeln mit Threads koordinieren AWT, Swing, JavaFX & SWT 5
C Threads Swing AWT, Swing, JavaFX & SWT 11
Z JavaFX Threads AWT, Swing, JavaFX & SWT 4
T hallo, habe ein Problem mit dem pro. eines Threads AWT, Swing, JavaFX & SWT 4
M Threads - nicht erklärbare Exception AWT, Swing, JavaFX & SWT 6
R Repaint() in Schleifen, Threads AWT, Swing, JavaFX & SWT 13
S Java Swing GUI mit MVC und Threads AWT, Swing, JavaFX & SWT 6
M Frage zu Threads AWT, Swing, JavaFX & SWT 3
C JTextArea scrollt bei append(String) aus Threads nicht ans Ende AWT, Swing, JavaFX & SWT 7
K Threads - Timer - run() mehrfach parallel? AWT, Swing, JavaFX & SWT 2
B GUI mit Threads aufbauen AWT, Swing, JavaFX & SWT 5
E Threads Ausgaben in GUI anzeigen lassen AWT, Swing, JavaFX & SWT 14
P JavaFX 2 (2.1 Beta) Threads AWT, Swing, JavaFX & SWT 7
B Threads in Swing AWT, Swing, JavaFX & SWT 4
M Problem mit Threads AWT, Swing, JavaFX & SWT 64
R Swing Java Swing Gui und nebenläufige Threads AWT, Swing, JavaFX & SWT 4
S Swing Threads Windows 7 64 bit AWT, Swing, JavaFX & SWT 12
J Threads + JFrame AWT, Swing, JavaFX & SWT 4
R Java threads und synchronized AWT, Swing, JavaFX & SWT 15
R Swing Swing und die Threads AWT, Swing, JavaFX & SWT 9
N Swing Threads sollen Tabtitel zur Laufzeit ändern AWT, Swing, JavaFX & SWT 4
M Zugriff paralleler Threads auf selbes JTextPane AWT, Swing, JavaFX & SWT 6
B Frage zu Swing,Threads, SwingWorker und Socket Communikation AWT, Swing, JavaFX & SWT 4
M Prioritäten bei SwingWorker / Threads AWT, Swing, JavaFX & SWT 9
B Swing GUI und Threads AWT, Swing, JavaFX & SWT 4
R Korrektes manipulieren der GUI aus anderen Threads heraus AWT, Swing, JavaFX & SWT 19
S Threads und Layout AWT, Swing, JavaFX & SWT 9
S Threads in einen Frame zeichnen lassen (Paint()?!) AWT, Swing, JavaFX & SWT 5
W GUI in mehreren Threads AWT, Swing, JavaFX & SWT 5
F Swing Anfängerproblem Threads AWT, Swing, JavaFX & SWT 6
S Swing Threads und das Ändern des Hintergrundes ... AWT, Swing, JavaFX & SWT 2
S Zeichnen in Threads AWT, Swing, JavaFX & SWT 4
T Auf Ende von mehreren Threads warten, ohne den EDT zu blockieren AWT, Swing, JavaFX & SWT 1
J SWT SWT und Threads AWT, Swing, JavaFX & SWT 5
borobudur SWT SWT-Framework und Threads AWT, Swing, JavaFX & SWT 12
W Threads nacheinander aufführen AWT, Swing, JavaFX & SWT 5
A Swing und Threads AWT, Swing, JavaFX & SWT 8
B JProgressbar wird nicht aktualisert, trotz Threads AWT, Swing, JavaFX & SWT 6
K Timer und Threads ruckeln für Fotoschwenk AWT, Swing, JavaFX & SWT 3
S JProgressBar und Threads AWT, Swing, JavaFX & SWT 11
G Probleme mit jList und Threads. AWT, Swing, JavaFX & SWT 3
R Swing & Threads AWT, Swing, JavaFX & SWT 4
R 2 Threads nacheinander. Einer terminiert, der andere nicht. AWT, Swing, JavaFX & SWT 9
J Unterschied zwischen SwingWorker und Threads AWT, Swing, JavaFX & SWT 4
P Threads und Swing bzw. AWT AWT, Swing, JavaFX & SWT 15
W Threads und trotzdem keine Nebenläufigkeit AWT, Swing, JavaFX & SWT 13
G Fenster erst nach Stoppen des Threads anzeigen AWT, Swing, JavaFX & SWT 3
N Threads kein neues Fenster erzeugen lassen AWT, Swing, JavaFX & SWT 4
G problem mit threads/repaint ! AWT, Swing, JavaFX & SWT 2
W Swing, 2 JProgressbars und threads geht das? AWT, Swing, JavaFX & SWT 2
A JTextArea und Threads AWT, Swing, JavaFX & SWT 9
B Probleme mit GUI und Threads AWT, Swing, JavaFX & SWT 17
E repaint(), EDT-Warteschlange und Threads AWT, Swing, JavaFX & SWT 26
S Threads in Java AWT, Swing, JavaFX & SWT 22
G AWT + Threads = nicht gut :P AWT, Swing, JavaFX & SWT 6
F Verständis Problem zu Threads AWT, Swing, JavaFX & SWT 2
M Swinganwendung Threads mit JProgressBar AWT, Swing, JavaFX & SWT 7
V Problem mit Aktualisieren von JList mit Threads AWT, Swing, JavaFX & SWT 3
U FileChooser Layout - Threads? AWT, Swing, JavaFX & SWT 17
R JProgressBar ohne Threads verwenden AWT, Swing, JavaFX & SWT 6
I JList, AbstractListModel und nebenläufige Threads AWT, Swing, JavaFX & SWT 2
S "Millionen" von Threads? Programm komplett beenden AWT, Swing, JavaFX & SWT 2
M Konsolenprg-Ausgabe in GUI geleitet - Brauche ich Threads? AWT, Swing, JavaFX & SWT 2
K Swing und Threads AWT, Swing, JavaFX & SWT 11
M Threads in Swing? AWT, Swing, JavaFX & SWT 2
C Schweres Problem mit JDialog und Threads! Anzeige blockiert! AWT, Swing, JavaFX & SWT 5
N Netzwerk-Applikation, SWT und Threads AWT, Swing, JavaFX & SWT 4
R createBufferStrategy() und Threads AWT, Swing, JavaFX & SWT 5
D Threads unter JFrame AWT, Swing, JavaFX & SWT 2
G Nochmal Threads und Einfrieren des GUI :( AWT, Swing, JavaFX & SWT 10
V Swing & Threads ??? AWT, Swing, JavaFX & SWT 3
D Problem mit JProgressBar und Threads AWT, Swing, JavaFX & SWT 7

Ähnliche Java Themen

Neue Themen


Oben