【发布时间】:2015-04-26 23:53:50
【问题描述】:
启动 MediaPlayer 的媒体块中没有空字段
我对此进行了广泛的研究,但没有发现任何可以解释此错误的原因。
我正在为一个类项目构建一个 Java Swing 应用程序,并尝试使用 JFX 面板和媒体播放器来托管和播放多个 mp4 视频。我已经成功让它工作了一次,但是当我再次回到窗口时,我遇到了错误。
java.lang.NullPointerException 在 com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMediaPlayer.playerSetBalance(未知 来源)在 com.sun.media.jfxmediaimpl.NativeMediaPlayer.setBalance(未知 源)在 javafx.scene.media.MediaPlayer.init(未知源)在 javafx.scene.media.MediaPlayer.(Unknown Source) at project.screens.TutorialPlayerScreen.initMediaPlayer(TutorialPlayerScreen.java:156) 在 project.screens.TutorialPlayerScreen.init(TutorialPlayerScreen.java:122) 在 project.screens.TutorialPlayerScreen.(TutorialPlayerScreen.java:113) 在 project.buttons.PreKModuleSelectTutorialButtons$Button$7.doAction(PreKModuleSelectTutorialButtons.java:225) 在 project.screens.PreKModuleSelect.clicked(PreKModuleSelect.java:359) 在 project.tools.ContentPane.notifiyObserver(ContentPane.java:457) 在 project.tools.ContentPane$1.mousePressed(ContentPane.java:272) 在 java.awt.Component.processMouseEvent(未知来源)在 javax.swing.JComponent.processMouseEvent(未知来源)在 java.awt.Component.processEvent(未知来源)在 java.awt.Container.processEvent(未知来源)在 java.awt.Component.dispatchEventImpl(未知来源)在 java.awt.Container.dispatchEventImpl(未知来源)在 java.awt.Component.dispatchEvent(未知来源)在 java.awt.LightweightDispatcher.retargetMouseEvent(未知来源)在 java.awt.LightweightDispatcher.processMouseEvent(未知来源)在 java.awt.LightweightDispatcher.dispatchEvent(未知来源)在 java.awt.Container.dispatchEventImpl(未知来源)在 java.awt.Window.dispatchEventImpl(未知来源)在 java.awt.Component.dispatchEvent(未知来源)在 java.awt.EventQueue.dispatchEventImpl(未知来源)在 java.awt.EventQueue.access$500(未知来源)在 java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) 在 java.security.ProtectionDomain$1.doIntersectionPrivilege(未知 来源)在 java.security.ProtectionDomain$1.doIntersectionPrivilege(未知 源)在 java.awt.EventQueue$4.run(未知源)在 java.awt.EventQueue$4.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) 在 java.security.ProtectionDomain$1.doIntersectionPrivilege(未知 源)在 java.awt.EventQueue.dispatchEvent(未知源)在 java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源) 在 java.awt.EventDispatchThread.pumpEventsForFilter(未知来源) 在 java.awt.EventDispatchThread.pumpEventsForHierarchy(未知 来源)在 java.awt.EventDispatchThread.pumpEvents(未知来源) 在 java.awt.EventDispatchThread.pumpEvents(Unknown Source) 在 java.awt.EventDispatchThread.run(未知来源)
这是我用来启动 JFX 媒体的代码:
' //媒体播放器支持 私人集团媒体根; 私有场景 mediaScene;
private Media tutorialVideo;
private MediaPlayer VideoPlayer;
private MediaView mediaViewer;
private JFXPanel fxPanel;
private int jfxPanelHeight = 394;//525;
private int jfxPanelWidth = 700;//700;
private void initMediaPlayer() throws IOException {
this.fxPanel = new JFXPanel(); //initializes JFX variables
fxPanel.setSize(this.jfxPanelWidth ,this.jfxPanelHeight);
//Add JFX Panel component to the Main Window
int padding = ((mainWindow.getPreferredSize().width - this.jfxPanelWidth) / 2);
mainWindow.addLayer(fxPanel, MEDIA_LAYER, padding, 125);
//Initialize FX Panel
this.mediaRoot = new Group();
this.mediaScene = new Scene(this.mediaRoot, 0, 0);
//Open/prepare the file
//String tutorialFilePath = new File("").getAbsolutePath() + DIRECTORY_PATH + "Tutorial.mp4";
String tutorialFilePath = new File("").getAbsolutePath() + MEDIA_PATH + this.observer.getName() +"Tutorial.mp4";
File mediaFile = new File(tutorialFilePath);
this.tutorialVideo = new Media(mediaFile.toURI().toString());
//Create the media player
this.VideoPlayer = new MediaPlayer(this.tutorialVideo); //Error here
this.VideoPlayer.setAutoPlay(false);
this.mediaViewer = new MediaView(this.VideoPlayer);
this.mediaViewer.setFitHeight(this.jfxPanelHeight);
this.mediaViewer.setFitWidth(this.jfxPanelWidth);
((Group)this.mediaScene.getRoot()).getChildren().add(this.mediaViewer);
fxPanel.setScene(this.mediaScene);
}'
我尝试在离开屏幕前清理已使用的内存。
public void tearDown(){
//Stop the JFX Player and Remove
this.mainWindow.removeLayer(this.fxPanel);
this.VideoPlayer.stop();
this.VideoPlayer.dispose();
this.fxPanel.removeAll();
this.mediaRoot.getChildren().removeAll();
this.mediaRoot = null;
this.mediaScene = null;
this.mediaViewer = null;
this.tutorialVideo = null;
this.VideoPlayer = null;
this.fxPanel = null;
}
private JLayeredPane contentPane; //The content pane of this JFrame.
public void removeLayer(JComponent component) {
contentPane.remove(component);
contentPane.revalidate();
contentPane.repaint();
}
任何帮助或评论将不胜感激!谢谢!
【问题讨论】:
-
tutorialFilePath是否真的指向一个有效的文件? -
@MadProgrammer 是的。第一次运行此代码工作正常。当我进行第二次启动时,我收到一个错误。这一行:this.VideoPlayer = new MediaPlayer(this.tutorialVideo); //这里出错
-
从到目前为止您向我们展示的内容很难推断,但在您调用
initMediaPlayer之前,您声明的字段之一肯定是null。 -
如果它先工作,然后在重新导航后抛出此异常,则在您更改视图时一定发生了一些变化。您的
tearDown()方法似乎很有可能是原因:当您不将这些值设置为null时会发生什么?你能这样缩小范围吗?您在该方法中删除了很多东西,也许某些东西没有被重建? -
这可能不是导致
NullPointerException的问题,但您需要在不同的线程上进行不同的方法调用。特别是,new JFXPanel()必须在 AWT 事件调度线程上调用,而initMediaPlayer的其余部分需要在 FX 应用程序线程上调用。请参阅JFXPaneljavadocs。 (虽然这可能不是问题的原因,但可以想象它是。)