Verständnisproblem Threads

myjday

Aktives Mitglied
Schönen guten Abend,

ich wollte zwei Kreise auf einem Panel kreisen lassen. Gleicher Radius, gleiche Sleeptime, nur dass sie sich entgegengesetzt drehen, sprich sich pro Umlauf zwei mal überlappen. tut aber nicht.
Er macht mir immer nur den zweiten Thread.
Habe einfach zwei neue Threads hintereinander angefügt.

Warum wechseln sich die Threads nicht ab? Ich hab sie doch beide auf den EDT gelegt????:L

Hier die Quellen:

Java:
import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Oberflaeche extends JFrame {

	static DrawPane p;
	static DrawPane q;

	public static void main(String[] args) {

		Runnable r = new Runnable() {

			public void run() {

				JFrame f = new JFrame("MyDraw 2010");

				f.setSize(new Dimension(500, 500));
				f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);

				p = new DrawPane();
				q = new DrawPane();

				f.add(p);
				f.add(q);
				f.setLocationRelativeTo(null);

				f.setVisible(true);
			}
		};

		EventQueue.invokeLater(r);

		new Thread() {

			public void run() {

				while (true) {

					EventQueue.invokeLater(new Runnable() {
						
						@Override
						public void run() {
							// TODO Auto-generated method stub
							
							int radius = 150;
							
							p.x = p.getWidth()/2 + (int) (radius * Math.cos(Math.toRadians(p.winkel)));
							p.y = p.getHeight()/2 + (int) (radius * Math.sin(Math.toRadians(p.winkel)));
							p.repaint();
							
							p.winkel++;
				
						}
					});
					
					
					try {
						Thread.sleep(10);
					} catch (InterruptedException in) {
					}

				}
			};

		}.start();

		new Thread() {

			public void run() {

				while (true) {

					EventQueue.invokeLater(new Runnable() {
						
						@Override
						public void run() {
							// TODO Auto-generated method stub
							
							int radius = 150;
							
							q.x = q.getWidth()/2 + (int) (radius * Math.cos(Math.toRadians(q.winkel)));
							q.y = q.getHeight()/2 + (int) (radius * Math.sin(Math.toRadians(q.winkel)));
							q.repaint();
							
							q.winkel--;

						}
					});
					
					
					try {
						Thread.sleep(10);
					} catch (InterruptedException in) {
					}

				}
			};

		}.start();
		
	}

}

und noch mein DrawPane

Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JPanel;

public class DrawPane extends JPanel {

	public int x;
	public int y;
	public int z;
	public int winkel;

	public DrawPane() {

		this.x = this.getWidth()/2;
		this.y = this.getHeight()/2;
		this.z = 20;
		this.winkel = 0;
	}

	@Override
	protected void paintComponent(Graphics g) {
		// TODO Auto-generated method stub
		super.paintComponent(g);

		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);

		g2.setColor(Color.RED);

		g2.fillOval(x, y, z, z);

	}
}

Idee?

Dane & Gruß,

myjday
 
Also wenn du zwei Threads auf dem EDT started, so wird zuerst der eine Thread ausgeführt. Ist dieser beendet, so wird der zweite ausgeführt.

Wenn du etwa auf dem EDT startest, so kommt das in die EventQueue. In einer Queue (Schlange) kann immer nur einer gleichzeitig dran kommen. Ist dieser fertig, so kommt der nächste dran (vgl. Schlange am Billetschalter und ein Kunde ist ein Thread. Da muss der eine Kunde warten, bis der andere fertig ist).

Wenn du mehrere Threads parallel laufen lassen willst, so darfst du diese auf keinen Fall auf dem EDT aufrufen. Die EventQueue wird sonst von einem Thread blockiert. Lediglich Initialisierungen und Änderungen an der Swing GUI müssen auf dem EDT passieren (diese Änderungen sollten nicht allzu lange dauern, sonst friert die GUI, ja sogar das Eventhandling ein).

Hoffe ich konnte dir helfen...
 
erstmal Vielen Dank für die schnelle Hilfe!

Dann hab ich das Prinzip noch nicht verstanden. Ich hab das so aufgefasst, dass ich alle Threads auf den EDT lege und dieser das so organisiert, dass für den User der Eindruck einer Quasiparalellität zwischen den Threads entsteht.

Na ja, ich werds mir nochmal anschauen ....

Gruß,
myjday
 
@icarus2: Schlafmangel? 😉

Das ganze hat mit Threads nichts zu tun, und icarus2 schreibt sonst glaubich auch eher vernünftige Sachen 😉 Das ganze funktioniert so und ist in bezug auf die Threads soweit ich das sehe vollkommen richtig. Das Problem ist, dass es zwei DrawPane-Instanzen gibt, und die Quasi "übereinandergemalt" werden müssten. Wenn man im Konstruktor sowas macht wie
Code:
                p = new DrawPane();
                q = new DrawPane();
                f.setLayout(null);
                f.add(p);
                f.add(q);
                p.setBounds(0,0,500,500);
                q.setBounds(0,0,500,500);
                p.setOpaque(false);
                q.setOpaque(false);
                f.setLocationRelativeTo(null);
funktioniert das auch alles. Aber besser wäre es natürlich, wenn es nur EIN DrawPane gäbe, das beliebig viele Kreise zeichnen könnte (das könnten dann z.B. objekte einer eigenen Klasse "Circle" sein, die eine Position speichert, die von den Threads verändert wird, und von denen dann mehrere in einer Liste im DrawPane liegen könnten...)
 
Mhm..wobei das invokeLater in den beiden Threads hier doch eig. unnötig ist und den Code nur mehr aufbläht, repaint() kann doch ruhig AFAIK aus jedem Thread aufgerufen werden?!
Ansonsten könnte man evtl. auch überlegen einen Timer/Swingtimer zu benutzen, dann spart man sich auch direkt das Thread.sleep ???:L
 
Ich hab schon wenig geschlafen... aber grad sooo wenig :-/ Ich hätte mir den Code wohl genauer ansehen sollen und besser überlegen was ich da überhaupt schreibe.

Naja, sorry für den Mist, den ich da oben verzapft habe. Ich sollte wohl besser mal ins Bett gehen ^^
 
Ja, wie viel man davon aus dem EDT rausziehn könnte, hatte ich auf überlegt. Im zweifelsfall könnte dort ALLES aus dem EDT raus, wenn das nicht das getWidth() drinstünde... vermutlich ist das da ziemlich wurscht (d.h. das könnte auch ohne EDT gemacht werden), aber "rein formal" muss es eben so sein...
 
Hallo Marco13,

es drehen sich zwei Kreise.

Vielen Dank an Alle. Ich versteh zwar noch nicht alles was ihr geschrieben habt, aber ich bleibe dran.

Gute Nacht ....
myjday
 

Zurück
Oben