Ich habe ein Programm mit einem Raumschiff (großer Kreis), das eine Kugel (kleiner Kreis) abfeuert, die nach einiger Zeit verschwindet. Jedes Mal, wenn es über einen bestimmten Teil des Codes läuft, erzeugt es einen Fehler (, aber es läuft weiter).Fehler: Ausnahme im Thread "JavaFX Application Thread"
Ich bin sicher, so dass das Problem in den folgenden Zeilen ist
private ArrayList<Bullet> bullets = new ArrayList<Bullet>();
//[...]
for (Bullet bullet : bullets) {
if (bullet.getLoops() > 50) {
bullets.remove(bullet); // specially in this line,
// because if I delete this, the error doesn't show up!
// I think it has something to do with the ArrayList.
} else {
bullet.next();
gc.strokeOval(bullet.getX() - 3, bullet.getY() - 3, 6, 6);
}
}
und das ist der Fehler, den ich bekommen:
Exception in thread "JavaFX Application Thread" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at sample.Main$4.handle(Main.java:131)
at javafx.animation.AnimationTimer$AnimationTimerReceiver.lambda$handle$484(AnimationTimer.java:57)
at java.security.AccessController.doPrivileged(Native Method)
at javafx.animation.AnimationTimer$AnimationTimerReceiver.handle(AnimationTimer.java:56)
at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:357)
at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:506)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
ich Ihnen gerne andere Informationen zu liefern, benötigt auf anfordern.
Prost. (Sorry für mein Englisch, ich bin aus Deutschland, aber ich habe Englisch seit einigen Jahren in der Schule.)
PS: wenn jemand den vollständigen Code des Mainclass benötigt:
package sample;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import java.util.ArrayList;
public class Main extends Application {
private Player p = new Player(100, 100, 0);
private ArrayList<Bullet> bullets = new ArrayList<Bullet>();
private static boolean left;
private static boolean right;
private static boolean up;
private static boolean down;
private static boolean shoot;
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
Group root0 = new Group();
Scene theScene = new Scene(root0, 500, 500);
primaryStage.setScene(theScene);
Canvas canvas = new Canvas(500, 500);
root0.getChildren().add(canvas);
theScene.setOnMouseMoved(
new EventHandler<MouseEvent>() {
public void handle(MouseEvent e) {
Vector a = new Vector(p.getX(), -p.getY());
Vector b = new Vector(e.getX(), -e.getY());
Vector c = new Vector(p.getX(), -p.getY() + 1);
p.setRotation(Vector.getAngle(a, b, c));
}
}
);
theScene.setOnKeyPressed(
new EventHandler<KeyEvent>() {
public void handle(KeyEvent e) {
String code = e.getCode().toString();
if (code.equals("A")) {
left = true;
}
if (code.equals("D")) {
right = true;
}
if (code.equals("W")) {
up = true;
}
if (code.equals("S")) {
down = true;
}
if (code.equals("SPACE")) {
if (!PlayerShot()) shoot = true;
}
}
}
);
theScene.setOnKeyReleased(
new EventHandler<KeyEvent>() {
public void handle(KeyEvent e) {
String code = e.getCode().toString();
if (code.equals("A")) {
left = false;
}
if (code.equals("D")) {
right = false;
}
if (code.equals("W")) {
up = false;
}
if (code.equals("S")) {
down = false;
}
if (code.equals("SPACE")) {
shoot = false;
}
}
}
);
GraphicsContext gc = canvas.getGraphicsContext2D();
Font theFont = Font.font("Helvetica", FontWeight.BOLD, 24);
gc.setFont(theFont);
gc.setStroke(Color.BLACK);
gc.setLineWidth(1);
new AnimationTimer() {
public void handle(long currentNanoTime) {
// Clear the canvas
gc.setFill(new Color(0.85, 0.85, 1.0, 1.0));
gc.fillRect(0, 0, 500, 500);
int x = p.getX();
int y = p.getY();
if (left && x >= 16) {
p.setX(x - 3);
}
if (right && x <= 500 - 16) {
p.setX(x + 3);
}
if (up && y >= 16) {
p.setY(y - 3);
}
if (down && y <= 500 - 16) {
p.setY(y + 3);
}
if (shoot) {
bullets.add(new Bullet(p.getX(), p.getY(), p.getRotationInVelocity(), p));
shoot = false;
}
gc.setStroke(Color.BLUE);
gc.strokeLine(p.getX(), p.getY(), p.getX() + Math.sin(p.getRotation()) * 16, p.getY() - Math.cos(p.getRotation()) * 16);
gc.strokeOval(p.getX() - 16, p.getY() - 16, 32, 32);
gc.setStroke(Color.RED);
for (Bullet bullet : bullets) {
if (bullet.getLoops() > 50) {
bullets.remove(bullet);
} else {
bullet.next();
gc.strokeOval(bullet.getX() - 3, bullet.getY() - 3, 6, 6);
}
}
}
}.start();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
// Hat der Spieler gerade eben schon geschossen?
public boolean PlayerShot() {
for (Bullet bullet : bullets) {
if(bullet.getShooter() == p)return true;
}
return false;
}
}
die anderen Klassen behandeln nur ein paar int-und Doppel-vars
öffentliche Leere nächste() { x + = velocity.getY() * 5; y + = -velocity.getX() * 5; Schleifen ++; } // Dies ist der Code, der die Vorwärtsbewegung behandelt und wenn ich ihn lösche kommt er nicht zu dem Teil mit dem "bullets.remove (bullet);" also kann es nicht erscheinen als. Aber das ist nicht die Lösung, die ich will! – doej1367
danke trotzdem :)! – doej1367