Threadfehler

Oetzicool

Erfahrenes Mitglied
Hey ich hab ein kleines Programm gemacht das einen Ball bewegt und dieser an den Wänden apprallt mit den Buttons "Start" und "Stop". Wenn ich auf Start drücke bewegt sich der Ball und mit Stop bleibt er an der aktuellen Position stehen aber wenn ich nochmal auf Start drück macht er nicht weiter was er eigentlich sollte! Könnt ihr mir den Fehler zeigen? Hier ist der Code:

Code:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

class ball extends Thread
{
 protected Panel p;
 protected Graphics g;
 protected int xa,ya,b,h;
 protected boolean fStop = false;
 public ball(Panel p, int b, int h)
 {
  this.p = p;
  this.b = b;
  this.h = h;
  g = p.getGraphics();
 }
 public void setP(int x,int y)
 {
   xa = y;
   ya = y;
 }
 public void show()
 {
   g.setColor(Color.red);
   g.drawOval(xa,ya,b,h);
 }
 public void hide()
 {
   g.setColor(Color.white);
   g.drawOval(xa,ya,b,h);
 }
 public void move(int xn, int yn)
  {
  hide();
  xa = xn;
  ya = yn;
  show();
  try
  {
    Thread.sleep(10);
  }
  catch(InterruptedException e)
  {
    g.drawString("Threadfehler",100,100);
  }
 }
 public void run()
  {
    setP(5,5);
    int dx = 2, dy = 2;
    fStop = false;
    do
    {
      if(xa>p.getSize().width-20)dx = -dx;
      if(xa<5)dx = -dx;
      if(ya>p.getSize().height-20)dy = -dy;
      if(ya<5)dy = -dy;
      move(xa+dx,ya+dy);
    }
    while(!fStop);
   }
}
public class BreakThru extends Applet implements ActionListener
{
  Panel p;
  Button start,stop;
  ball ball_br;
  public void init()
  {
    p = new Panel();
    start = new Button("Start");
    stop = new Button("Stop");
    this.setBackground(Color.blue);
    this.setLayout(null);
    p.setBounds(5,5,400,200);
    p.setBackground(Color.white);
    this.add(p);
    start.setBounds(100,210,50,20);
    start.setBackground(Color.lightGray);
    start.addActionListener(this);
    this.add(start);
    stop.setBounds(200,210,50,20);
    stop.setBackground(Color.lightGray);
    stop.addActionListener(this);
    this.add(stop);
    ball_br = new ball(p,20,20);
  }
  public void actionPerformed(ActionEvent e)
  {
    if(e.getSource()==start)
    {
    ball_br.start();
    ball_br.fStop=false;
    }
    if(e.getSource()==stop)ball_br.fStop = true;
  }
}
 
Ein Thread der beendet wurde kann nicht erneut gestartet werden. Daher bekommst du dann eine Exception.

Daher muss ein neuer Thread erstellt werden mit den Daten vom alten Thread damit der Ball nahtlos weiterfliegt.

Und Klassennamen immer gross schreiben ;)

Java:
package de.tutorials;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

class BallInfo {
	protected int xa = 5, ya = 5;

	protected int b, h;

	protected int dx = 2, dy = 2;

	public BallInfo(int b, int h) {
		this.b = b;
		this.h = h;
	}
}

class Ball extends Thread {

	protected Panel p;

	protected Graphics g;

	protected BallInfo info;

	protected boolean fStop = false;

	public Ball(Panel p, int b, int h) {
		this.p = p;
		this.info = new BallInfo(b, h);
		g = p.getGraphics();
	}

	public Ball(Panel p, BallInfo info) {
		this.p = p;
		this.info = info;
		g = p.getGraphics();
	}

	public void show() {
		g.setColor(Color.red);
		g.drawOval(info.xa, info.ya, info.b, info.h);
	}

	public void hide() {
		g.setColor(Color.white);
		g.drawOval(info.xa, info.ya, info.b, info.h);
	}

	public void move(int xn, int yn) {
		hide();
		info.xa = xn;
		info.ya = yn;
		show();
	}

	public void run() {
		fStop = false;
		do {
			if (info.xa > p.getSize().width - 20)
				info.dx = -info.dx;
			if (info.xa < 5)
				info.dx = -info.dx;
			if (info.ya > p.getSize().height - 20)
				info.dy = -info.dy;
			if (info.ya < 5)
				info.dy = -info.dy;
			move(info.xa + info.dx, info.ya + info.dy);

			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				g.drawString("Threadfehler", 100, 100);
			}
		} while (!fStop);
	}
}

public class BreakThru extends Applet implements ActionListener {
	private Panel p;

	private Button start, stop;

	private Ball ball_br;

	public void init() {
		p = new Panel();
		start = new Button("Start");
		stop = new Button("Stop");
		this.setBackground(Color.blue);
		this.setLayout(null);
		p.setBounds(5, 5, 400, 200);
		p.setBackground(Color.white);
		this.add(p);
		start.setBounds(100, 210, 50, 20);
		start.setBackground(Color.lightGray);
		start.addActionListener(this);
		this.add(start);
		stop.setBounds(200, 210, 50, 20);
		stop.setBackground(Color.lightGray);
		stop.addActionListener(this);
		this.add(stop);
		ball_br = new Ball(p, 20, 20);
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == start) {
			ball_br.start();
			ball_br.fStop = false;
		}
		if (e.getSource() == stop) {
			ball_br.fStop = true;
			ball_br = new Ball(p, ball_br.info);
		}
	}
}
 
Und wie kann ich es machen das der Thread von anfang startet also da wo die startposition ist?
 
Zuletzt bearbeitet:
Machen kannst das wie du willst wenns denn geht ;)

Allgemein sollte man aber GUI und die Daten die die GUI anzeigt trennen. Daher ist es sinnvoll die Position des Balls und die Darstellung zu trennen wie ich das zumindest teilweise schon gemacht habe.

Ich weiss aber nicht wo das Problem ist xa und ya wieder zu setzen?

Java:
ball_br = new Ball(p, ball_br.info);
ball_br.info.xa = 5;
ball_br.info.ya = 5;
 
Also ich hab den Code ein wenig angepasst so wie ich das haben will also mit dem Spiel! Kannst du mir erklären wie ich es hier hinkrieg das wenn ich auf Stop geh er wieder auf die anfangswerte zurückgesetzt wird und bei Start von vorne anfängt

Code:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

class ball extends Thread
{
 protected Panel p;
 protected Graphics g;
 protected int xa,ya,r_ball;
 protected boolean fStop = false;
 //Wand 1
 int li1_xa=25,li1_ya=220,li1_xe=25,li1_ye=20;
 //Wand 2
 int li2_xa=25,li2_ya=20,li2_xe=275,li2_ye=20;
 //Wand 3
 int li3_xa=275,li3_ya=220,li3_xe=275,li3_ye=20;
 public ball(Panel p, int r_ball)
 {
  this.p = p;
  this.r_ball = r_ball;
  g = p.getGraphics();
 }
 public void setP(int x,int y)
 {
   xa = y;
   ya = y;
 }
 public void drawLines()
 {
   g.drawLine(li1_xa,li1_ya,li1_xe,li1_ye);
   g.drawLine(li2_xa,li2_ya,li2_xe,li2_ye);
   g.drawLine(li3_xa,li3_ya,li3_xe,li3_ye);
 }
 public void show()
 {
   g.setColor(Color.red);
   g.drawOval(xa,ya,r_ball,r_ball);
 }
 public void hide()
 {
   g.setColor(Color.white);
   g.drawOval(xa,ya,r_ball,r_ball);
 }
 public void move(int xn, int yn)
  {
  hide();
  xa = xn;
  ya = yn;
  show();
  try
  {
    Thread.sleep(10);
  }
  catch(InterruptedException e)
  {
    g.drawString("Threadfehler",100,100);
  }
 }
 public void run()
  {
    setP(100,100);
    int dx = 1, dy = 1;
    fStop = false;
    do
    {
      drawLines();
      if(xa>li3_xa-r_ball)dx = -dx;
      if(xa<25)dx = -dx;
      if(ya>300)dy = -dy;
      if(ya<li2_ya)dy = -dy;
      move(xa+dx,ya+dy);
    }
    while(!fStop);
   }
}
public class BreakThru extends Applet implements ActionListener
{
  Panel p;
  Button start,stop;
  ball ball_br;
  public void init()
  {
    p = new Panel();
    start = new Button("Start");
    stop = new Button("Stop");
    this.setBackground(Color.blue);
    this.setLayout(null);
    p.setBounds(50,5,300,265);
    p.setBackground(Color.white);
    this.add(p);
    start.setBounds(100,275,50,20);
    start.setBackground(Color.lightGray);
    start.addActionListener(this);
    this.add(start);
    stop.setBounds(200,275,50,20);
    stop.setBackground(Color.lightGray);
    stop.addActionListener(this);
    this.add(stop);
    ball_br = new ball(p,20);
  }
  public void actionPerformed(ActionEvent e)
  {
    if(e.getSource()==start)
    {
    ball_br.start();
    ball_br.fStop=false;
    }
    if(e.getSource()==stop)
    {
    ball_br.fStop = true;
    }

  }
}
 
Da du keine meiner Vorschläge annimmst weiss ich nicht was ich jetzt noch dazu sagen soll.
 
:) hehe, nein natürlich nehm ich deine Hilfe dankend an nur ich weiß bei meinem obigen Beispiel einfach nicht wie ich des einbinden soll wollt nur wissen ob du mir des an meinem Code demonstrieren kannst?
 
Zurück