2013-04-25 35 views
0

我正在开发一个JavaFx应用程序。应用程序创建多个线程(相同的类)。 在这里创建的线程:JavaFx,多线程应用程序,奇怪的异常

这是Thread类的run方法:

 public void run() { 
    //this.controller.run(this.turtle, this.finish); 

    long speed = 500; 
    double step = 20; //10 pixeli 

    while (turtle.getX() < finish) { 
     Random random = new Random(); 

     controller.modifyTurtlePosition(turtle, speed, step); 

     if (Math.random() < 0.2) { 
      if (Math.random() < 0.5) { 
       if (speed > 100) 
        speed -= random.nextLong() % (((double)1/3) * speed); 
      } else { 
       if (speed < 1500) 
        speed += random.nextLong() % (((double)1/3) * speed); 
      } 
     } 
    } 
} 

而且这是在控制器方法 “modifyTurtlePositions(...)”:

public void modifyTurtlePosition(final ImageView turtle, long speed, double step) { 
    Timeline timeline = new Timeline(); 

    final double newX = turtle.getX() + step; 

    KeyValue keyValue = new KeyValue(turtle.xProperty(), turtle.getX() + step); 
    KeyFrame keyFrame = new KeyFrame(Duration.millis(speed), keyValue); 

    timeline.getKeyFrames().add(keyFrame); 

    timeline.setOnFinished(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      turtle.setX(newX); 
     } 
    }); 

    timeline.play(); 

    try { 
     Thread.sleep(speed); 
    } catch (InterruptedException e) { 
     System.err.println(e.getMessage()); 
    } 
} 

问题是,如果我不使这种方法同步,我会得到以下异常:

Exception in thread "Thread-16" java.lang.ArrayIndexOutOfBoundsException: 2 
at java.util.ArrayList.add(ArrayList.java:412) 
at com.sun.scenario.animation.AbstractMasterTimer.addPulseReceiver(AbstractMasterTimer.java:211) 
at com.sun.scenario.animation.shared.AnimationPulseReceiver.addPulseReceiver(AnimationPulseReceiver.java:70) 
at com.sun.scenario.animation.shared.AnimationPulseReceiver.start(AnimationPulseReceiver.java:84) 
at javafx.animation.Animation.play(Animation.java:775) 
at javafx.animation.Animation.play(Animation.java:762) 
at sample.Controller.modifyTurtlePosition(Controller.java:95) 
at sample.TurtleRunThread.run(TurtleRunThread.java:35) 
    java.lang.NullPointerException 
at  com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:366) 
at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:289) 
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:456) 
at com.sun.javafx.tk.quantum.QuantumToolkit$9.run(QuantumToolkit.java:329) 
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29) 
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73) 
at java.lang.Thread.run(Thread.java:722) 

你有什么想法吗?

回答

4

包装controller.modifyTurtlePosition(turtle, speed, step);Platform.runLater()

Platform.runLater(new Runnable() { 
    public void run() { 
     controller.modifyTurtlePosition(turtle, speed, step); 
    } 
} 

所有的UI操作必须在UI线程来完成。

相关问题