2013-04-25 3 views
0

JavaFx 응용 프로그램에서 작업하고 있습니다. 응용 프로그램이 여러 스레드 (같은 클래스)를 만듭니다. 이 스레드 클래스의 실행 방법JavaFx, 멀티 스레딩 응용 프로그램, 이상한 예외

: 스레드가 여기에 생성됩니다

 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 스레드에서 수행해야합니다.

관련 문제