I need to be able to play Audio files (MP3 / Wav) in a normal Java project. I’d prefer using the new JavaFX MediaPlayer rather than JMF. I wrote some code to test this:
public void play()
{
URL thing = getClass().getResource("mysound.wav");
Media audioFile = new Media( thing.toString() );
try
{
MediaPlayer player = new MediaPlayer(audioFile);
player.play();
}
catch (Exception e)
{
System.out.println( e.getMessage() );
System.exit(0);
}
}
When I run this, I get the exception: Toolkit not initialized
I get that this has something to do with the JavaFX thread. My question is, how can I solve this? Do I need to create a JavaFX Panel just to play some audio files in the background of my normal app, or is there any other way?
Edit: Stacktrace:
java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:121)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:116)
at javafx.application.Platform.runLater(Platform.java:52)
at javafx.scene.media.MediaPlayer.init(MediaPlayer.java:445)
at javafx.scene.media.MediaPlayer.<init>(MediaPlayer.java:360)
at javaapplication6.JavaApplication6.play(JavaApplication6.java:23)
at javaapplication6.JavaApplication6.main(JavaApplication6.java:14)
For a solution with integrates a JavaFX MediaPlayer in Swing
Use a JFXPanel and be careful to only use JavaFX objects on the JavaFX thread and after the JavaFX system has been properly initialized.
JavaFX is normal Java which makes the question a bit confusing, but I guess you mean Swing.
Here’s a sample audio player which is launched from Swing. The sample assumes that there are a bunch of mp3 files in the default public sample music folder for Windows 7 (C:\Users\Public\Music\Sample Music) and plays each file in turn.
JavaFXMediaPlayerLaunchedFromSwing.java
This code is responsible for creating a Swing application which, in turn, initializes the JavaFX toolkit and creates a JavaFX scene on the JavaFX application thread.
MediaSceneGenerator.java
Creates a JavaFX media player which sequentially plays all of the
.mp3media files in a given folder. It provides some controls for the media (play, pause, skip track, current track play progress indicator).If you just want a native JavaFX application with a MediaPlayer and no Swing
The solution above which uses Swing answers the question asked. However, I have noted that sometimes people have picked up this answer and used it to create Java based media players even when they don’t have an existing Swing application that they are embedding their application into.
If you don’t have an existing Swing application, then eliminate the Swing code completely from your application and write a native JavaFX application instead. To do this, use the
JavaFXMediaPlayerclass below instead of the classJavaFXMediaPlayerLaunchedFromSwingfrom the sample above.JavaFXMediaPlayer
Answers to follow-up questions
Note: info in this follow-up answer on packaging is likely dated now and other preferred packaging options exist at this time (e.g https://github.com/openjfx/javafx-maven-plugin).
Technically, Swing doesn’t build Jar files but the jar of javafx packaging commands do.
If your app contains JavaFX, then, it’s best to use the JavaFX packaging tools. Without them, you may have some deployment issues issues as the Java runtime jar (jfxrt.jar) is not automatically on the java boot classpath for jdk7u7. Users can manually add it to their runtime classpath, but it could be a bit of a pain. In future jdk versions (perhaps jdk7u10 or jdk8), jfxrt.jar will be on the classpath. Even then, use of the JavaFX packaging tools would still be recommended as it will be the best way to ensure that your deployment package will work in the most compatible way.
The SwingInterop NetBeans project is a sample NetBeans project which utilizes JavaFX deployment tools for a Swing project embedding JavaFX components. Source for SwingInterop is part of the JDK 7 and JavaFX Demos and Samples download.