Playing audio using JavaFX MediaPlayer in a regular Java application?

I need to be able to play audio files (MP3 / Wav) in a regular Java project. I would prefer to use the new JavaFX MediaPlayer rather than JMF. I wrote code to verify 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 an exception: Toolkit is not initialized

I understand 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 only to play some audio files in the background of a regular application or is there another 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) 
+8
source share
1 answer

For a solution with integrated JavaFX MediaPlayer in Swing

Use the JFXPanel and be careful to use JavaFX objects only in the JavaFX stream and after proper initialization of the JavaFX system.

JavaFX is just plain Java, which makes the question a bit confusing, but I think you mean Swing.

Here is an example of an audio player that starts from Swing. The example assumes that in the public folder with music samples for Windows 7, by default there are several mp3 files (C: \ Users \ Public \ Music \ Sample Music), and each file is played in turn.

app screenshot

JavaFXMediaPlayerLaunchedFromSwing.java

This code is responsible for creating the Swing application, which in turn initializes the JavaFX toolkit and creates the JavaFX scene in the JavaFX application thread.

 import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javax.swing.*; /** * Example of playing all mp3 audio files in a given directory * using a JavaFX MediaView launched from Swing */ public class JavaFXMediaPlayerLaunchedFromSwing { private static void initAndShowGUI() { // This method is invoked on Swing thread JFrame frame = new JFrame("FX"); final JFXPanel fxPanel = new JFXPanel(); frame.add(fxPanel); frame.setBounds(200, 100, 800, 250); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setVisible(true); Platform.runLater(() -> initFX(fxPanel)); } private static void initFX(JFXPanel fxPanel) { // This method is invoked on JavaFX thread Scene scene = new MediaSceneGenerator().createScene(); fxPanel.setScene(scene); } public static void main(String[] args) { SwingUtilities.invokeLater( JavaFXMediaPlayerLaunchedFromSwing::initAndShowGUI ); } } 

MediaSceneGenerator.java

Creates a JavaFX media player that sequentially plays all .mp3 media files in the specified folder. It provides some controls for multimedia (play, pause, skip track, progress indicator of playback of the current track).

 import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.scene.layout.VBox; import javafx.scene.media.*; import javafx.util.Duration; import java.io.File; import java.util.*; public class MediaSceneGenerator { private static final String MUSIC_FOLDER = "C:\\Users\\Public\\Music\\Sample Music"; private static final String MUSIC_FILE_EXTENSION = ".mp3"; private final Label currentlyPlaying = new Label(); private final ProgressBar progress = new ProgressBar(); private ChangeListener<Duration> progressChangeListener; public Scene createScene() { final StackPane layout = new StackPane(); // determine the source directory for the playlist final File dir = new File(MUSIC_FOLDER); if (!dir.exists() || !dir.isDirectory()) { System.out.println("Cannot find media source directory: " + dir); Platform.exit(); return null; } // create some media players. final List<MediaPlayer> players = new ArrayList<>(); for (String file : Objects.requireNonNull(dir.list((dir1, name) -> name.endsWith(MUSIC_FILE_EXTENSION)))) players.add( createPlayer( normalizeFileURL(dir, file) ) ); if (players.isEmpty()) { System.out.println("No audio found in " + dir); Platform.exit(); return null; } // create a view to show the mediaplayers. final MediaView mediaView = new MediaView(players.get(0)); final Button skip = new Button("Skip"); final Button play = new Button("Pause"); // play each audio file in turn. for (int i = 0; i < players.size(); i++) { MediaPlayer player = players.get(i); MediaPlayer nextPlayer = players.get((i + 1) % players.size()); player.setOnEndOfMedia(() -> { final MediaPlayer curPlayer = mediaView.getMediaPlayer(); nextPlayer.seek(Duration.ZERO); if (nextPlayer != curPlayer) { curPlayer.currentTimeProperty().removeListener(progressChangeListener); } mediaView.setMediaPlayer(nextPlayer); nextPlayer.play(); }); } // allow the user to skip a track. skip.setOnAction(actionEvent -> { final MediaPlayer curPlayer = mediaView.getMediaPlayer(); MediaPlayer nextPlayer = players.get((players.indexOf(curPlayer) + 1) % players.size()); nextPlayer.seek(Duration.ZERO); mediaView.setMediaPlayer(nextPlayer); if (nextPlayer != curPlayer) { curPlayer.currentTimeProperty().removeListener(progressChangeListener); } nextPlayer.play(); }); // allow the user to play or pause a track. play.setOnAction(actionEvent -> { if ("Pause".equals(play.getText())) { mediaView.getMediaPlayer().pause(); play.setText("Play"); } else { mediaView.getMediaPlayer().play(); play.setText("Pause"); } }); // display the name of the currently playing track. mediaView.mediaPlayerProperty().addListener( (observableValue, oldPlayer, newPlayer) -> setCurrentlyPlaying(newPlayer) ); // start playing the first track. mediaView.setMediaPlayer(players.get(0)); mediaView.getMediaPlayer().play(); setCurrentlyPlaying(mediaView.getMediaPlayer()); // silly invisible button used as a template to get the actual preferred size of the Pause button. Button invisiblePause = new Button("Pause"); invisiblePause.setVisible(false); play.prefHeightProperty().bind(invisiblePause.heightProperty()); play.prefWidthProperty().bind(invisiblePause.widthProperty()); // layout the scene. HBox controls = new HBox(10, skip, play, progress); controls.setAlignment(Pos.CENTER); VBox mediaPanel = new VBox(10, currentlyPlaying, mediaView, controls); layout.setStyle("-fx-background-color: cornsilk; -fx-font-size: 20; -fx-padding: 20; -fx-alignment: center;"); layout.getChildren().addAll( invisiblePause, mediaPanel ); progress.setMaxWidth(Double.MAX_VALUE); HBox.setHgrow(progress, Priority.ALWAYS); return new Scene(layout); } /** * sets the currently playing label to the label of the new media player and updates the progress monitor. */ private void setCurrentlyPlaying(final MediaPlayer newPlayer) { progress.setProgress(0); progressChangeListener = (observableValue, oldValue, newValue) -> progress.setProgress( 1.0 * newPlayer.getCurrentTime().toMillis() / newPlayer.getTotalDuration().toMillis() ); newPlayer.currentTimeProperty().addListener(progressChangeListener); String source = getUserFriendlyMediaName(newPlayer); currentlyPlaying.setText("Now Playing: " + source); } /** * @return a MediaPlayer for the given source which will report any errors it encounters */ private MediaPlayer createPlayer(String aMediaSrc) { System.out.println("Creating player for: " + aMediaSrc); final MediaPlayer player = new MediaPlayer(new Media(aMediaSrc)); player.setOnError(() -> System.out.println("Media error occurred: " + player.getError())); return player; } private String normalizeFileURL(File dir, String file) { return "file:///" + (dir + "\\" + file).replace("\\", "/").replaceAll(" ", "%20"); } private String getUserFriendlyMediaName(MediaPlayer newPlayer) { String source = newPlayer.getMedia().getSource(); source = source.substring(0, source.length() - MUSIC_FILE_EXTENSION.length()); source = source.substring(source.lastIndexOf("/") + 1).replaceAll("%20", " "); return source; } } 

If you just need your own JavaFX application with MediaPlayer and without Swing

The solution above that uses Swing answers the question asked. However, I noted that sometimes people choose this answer and use it to create Java-based media players, even if they don’t have an existing Swing application in which they embed their application.

If you do not have an existing Swing application, completely remove the Swing code from your application and instead write your own JavaFX application. To do this, use the JavaFXMediaPlayer class below instead of the JavaFXMediaPlayerLaunchedFromSwing class from the example above.

JavaFXMediaPlayer

 import javafx.application.Application; import javafx.stage.Stage; public class JavaFXMediaPlayer extends Application { @Override public void start(Stage stage) throws Exception { stage.setScene(new MediaSceneGenerator().createScene()); stage.show(); } } 

Answers to the following questions

Will JavaFX automatically be added to my .JAR file created with Swing after I add it to the libraries in NetBeans?

Note: the information in this subsequent packaging answer is probably out of date, and other packaging preferences currently exist (e.g. https://github.com/openjfx/javafx-maven-plugin ).

Technically, Swing does not create Jar files, but makes Jar from javafx packaging commands.

If your application contains JavaFX, it is best to use JavaFX packaging tools . Without them, you might have deployment problems, because the Java runtime jar (jfxrt.jar) is not automatically in the java download path for jdk7u7. Users can manually add it to the classpath at runtime, but it can be a little painful. In future versions of jdk (possibly jdk7u10 or jdk8), the jfxrt.jar file will be in the class path. Even so, it is recommended that you use the JavaFX packaging tools, as this will be the best way to ensure that your deployment package works in the most compatible way.

The NetBeans project SwingInterop is an example of a NetBeans project that uses the JavaFX deployment tools for a Swing project in which JavaFX components are embedded. The source for SwingInterop is part of the JDK 7 download and JavaFX sample files and examples .

+17
source

All Articles