在普通的Java应用程序中使用JavaFX MediaPlayer播放音频?

我需要能够在普通的Java项目中播放音频文件(MP3 / Wav)。 我更喜欢使用新的JavaFX MediaPlayer而不是JMF。 我写了一些代码来测试这个:

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); } } 

当我运行它时,我得到了exception:Toolkit未初始化

我知道这与JavaFX线程有关。 我的问题是,我该如何解决这个问题? 我是否需要创建一个JavaFX Panel才能在我的普通应用程序的后台播放一些音频文件,或者还有其他方法吗?

编辑: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.(MediaPlayer.java:360) at javaapplication6.JavaApplication6.play(JavaApplication6.java:23) at javaapplication6.JavaApplication6.main(JavaApplication6.java:14) 

使用JFXPanel并小心只在JavaFX线程上使用JavaFX对象,并且在正确初始化JavaFX系统之后。

JavaFX是普通的Java,这使得这个问题有点令人困惑,但我想你的意思是Swing。

这是一个从中发布的示例音频播放器。 该示例假定Windows 7的默认公共示例音乐文件夹(C:\ Users \ Public \ Music \ Sample Music)中有一堆mp3文件,并依次播放每个文件。

 import java.io.*; import java.util.*; import javafx.application.Platform; import javafx.beans.value.*; import javafx.embed.swing.JFXPanel; import javafx.event.*; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.scene.media.*; import javafx.util.Duration; import javax.swing.*; /** Example of playing all mp3 audio files in a given directory * using a JavaFX MediaView launched from Swing */ public class JavaFXVideoPlayerLaunchedFromSwing { 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(new Runnable() { @Override public void run() { initFX(fxPanel); } }); } private static void initFX(JFXPanel fxPanel) { // This method is invoked on JavaFX thread Scene scene = new SceneGenerator().createScene(); fxPanel.setScene(scene); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { initAndShowGUI(); } }); } } class SceneGenerator { final Label currentlyPlaying = new Label(); final ProgressBar progress = new ProgressBar(); private ChangeListener progressChangeListener; public Scene createScene() { final StackPane layout = new StackPane(); // determine the source directory for the playlist final File dir = new File("C:\\Users\\Public\\Music\\Sample Music"); if (!dir.exists() || !dir.isDirectory()) { System.out.println("Cannot find video source directory: " + dir); Platform.exit(); return null; } // create some media players. final List players = new ArrayList(); for (String file : dir.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith(".mp3"); } })) players.add(createPlayer("file:///" + (dir + "\\" + file).replace("\\", "/").replaceAll(" ", "%20"))); 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++) { final MediaPlayer player = players.get(i); final MediaPlayer nextPlayer = players.get((i + 1) % players.size()); player.setOnEndOfMedia(new Runnable() { @Override public void run() { player.currentTimeProperty().removeListener(progressChangeListener); mediaView.setMediaPlayer(nextPlayer); nextPlayer.play(); } }); } // allow the user to skip a track. skip.setOnAction(new EventHandler() { @Override public void handle(ActionEvent actionEvent) { final MediaPlayer curPlayer = mediaView.getMediaPlayer(); MediaPlayer nextPlayer = players.get((players.indexOf(curPlayer) + 1) % players.size()); mediaView.setMediaPlayer(nextPlayer); curPlayer.currentTimeProperty().removeListener(progressChangeListener); curPlayer.stop(); nextPlayer.play(); } }); // allow the user to play or pause a track. play.setOnAction(new EventHandler() { @Override public void handle(ActionEvent 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(new ChangeListener() { @Override public void changed(ObservableValue observableValue, MediaPlayer oldPlayer, MediaPlayer 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. layout.setStyle("-fx-background-color: cornsilk; -fx-font-size: 20; -fx-padding: 20; -fx-alignment: center;"); layout.getChildren().addAll( invisiblePause, VBoxBuilder.create().spacing(10).alignment(Pos.CENTER).children( currentlyPlaying, mediaView, HBoxBuilder.create().spacing(10).alignment(Pos.CENTER).children(skip, play, progress).build() ).build() ); progress.setMaxWidth(Double.MAX_VALUE); HBox.setHgrow(progress, Priority.ALWAYS); return new Scene(layout, 800, 600); } /** 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 = new ChangeListener() { @Override public void changed(ObservableValue observableValue, Duration oldValue, Duration newValue) { progress.setProgress(1.0 * newPlayer.getCurrentTime().toMillis() / newPlayer.getTotalDuration().toMillis()); } }; newPlayer.currentTimeProperty().addListener(progressChangeListener); String source = newPlayer.getMedia().getSource(); source = source.substring(0, source.length() - ".mp4".length()); source = source.substring(source.lastIndexOf("/") + 1).replaceAll("%20", " "); 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(new Runnable() { @Override public void run() { System.out.println("Media error occurred: " + player.getError()); } }); return player; } } 

我将通过swing构建的.JAR文件自动添加到JavaFX中,一旦我将其添加到netbeans中的库中吗?

从技术上讲,Swing不会构建Jar文件,但javafx包装命令的jar会这样做。

如果您的应用程序包含JavaFX,那么最好使用JavaFX打包工具 。 没有它们,您可能会遇到一些部署问题,因为Java运行时jar(jfxrt.jar)不会自动出现在jdk7u7的java引导类路径中。 用户可以手动将其添加到运行时类路径中,但这可能有点痛苦。 在将来的jdk版本(可能是jdk7u10或jdk8)中,jfxrt.jar将位于类路径中。 即使这样,仍然建议使用JavaFX打包工具,因为这将是确保您的部署包以最兼容的方式工作的最佳方法。

SwingInterop NetBeans项目是一个示例NetBeans项目,它利用JavaFX部署工具来嵌入JavaFX组件的Swing项目。 SwingInterop的源代码是JDK 7和JavaFX演示和示例下载的一部分。