2015-02-08 59 views
0

我正在玩JMonkeyEngine。 当我这样做时,我玩JavaFX MediaPlayer。 这MediaPlayer的需要一个Runnable处理什么做的,当媒体完成:Runnable并发性

mp.setOnEndOfMedia(new Runnable() { 
@Override public void run() { 
}} 

我想做某事。像这样:

mp.setOnEndOfMedia(new Runnable() { 
    @Override public void run() { 
    // instance.toggleLists(); 
     initMediaPlayer(mediaView, actualList.getPath()+actualList.getMediaLocation()); 
     detachChild(node); 
     node = new TextureNode("mediaManagerTextureNode"); 
     node.init(app, mp); 
     attachChild(node); 
    } 
}); 

这是工作了几次,但最后我遇到了一些运行时错误。

java.lang.IllegalStateException: Scene graph is not properly updated for rendering. 
State was changed after rootNode.updateGeometricState() call. 
Make sure you do not modify the scene from another thread! 
Problem spatial name: Root Node 

是的,的确如此。我从外面搞乱了那个线程。 因为我对这个东西有点不习惯...... 我不需要在该运行方法的那个位置做那件事,它只是在运行时必须做的事情。

什么是最好的方式来传递工作,以便我的普通更新电话可以做家务? 我已经试图建立一个标志,将其设置为true,如果为true,则通过应用程序本身的标准更新调用更新该标志,但不知何故,我遇到了这个错误。这对我没有多大帮助。

MediaPlayer只需告诉我的应用程序“嘿!我准备好了!给我一个休息时间,让我有新的东西!” 也就是说,该运行方法中发生了什么。

回答

0

您可以在下次更新使用Application.enqueue做一个Runnable运行在主线程上 - 像这样:(假设app是一个参考应用程序)

mp.setOnEndOfMedia(new Runnable() { 
    @Override public void run() { 
     app.enqueue(new Runnable() { 
      @Override public void run() { 
       initMediaPlayer(mediaView, actualList.getPath()+actualList.getMediaLocation()); 
       detachChild(node); 
       node = new TextureNode("mediaManagerTextureNode"); 
       node.init(app, mp); 
       attachChild(node); 
      } 
     }); 
    } 
}); 

如果您使用的是Java 8,您可以使用lambda表达式将其缩写为:

mp.setOnEndOfMedia(() -> {app.enqueue(() -> { 
    initMediaPlayer(mediaView, actualList.getPath()+actualList.getMediaLocation()); 
    detachChild(node); 
    node = new TextureNode("mediaManagerTextureNode"); 
    node.init(app, mp); 
    attachChild(node); 
}});