打在一个正常的Java应用程序中使用JavaFX MediaPlayer的声音?(Playing a

2019-06-18 06:36发布

我需要能够在一个正常的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);
    }        
}

当我运行它,我得到异常:工具包未初始化

我得到这个事做的JavaFX线程。 我的问题是,我该如何解决这个问题? 我需要创建一个JavaFX面板只是在我的正常应用程序的后台播放一些音频文件,或有任何其他方式?

编辑:堆栈跟踪:

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)

Answer 1:

使用JFXPanel并注意对JavaFX的线程和JavaFX的系统已经正确初始化后只使用JavaFX的对象。

JavaFX是普通的Java使这个问题有点混乱,但我猜你的意思摆动。

下面是它从推出样品音频播放器。 该示例假定有针对Windows 7默认的公共示例音乐文件夹中的一堆MP3文件(C:\用户\公用\音乐\示例音乐),并播放每个文件反过来。

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<Duration> 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<MediaPlayer> players = new ArrayList<MediaPlayer>();
    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<ActionEvent>() {
      @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<ActionEvent>() {
      @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<MediaPlayer>() {
      @Override public void changed(ObservableValue<? extends MediaPlayer> 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<Duration>() {
      @Override public void changed(ObservableValue<? extends Duration> 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;
  }
}

请问我的.jar文件通过摆动内置自动已JavaFX的加入一次我在NetBeans将它添加到库中?

从技术上讲,挥杆不建立Jar文件,但JavaFX的包装命令的罐子做的。

如果您的应用包含JavaFX的话,最好还是用JavaFX打包工具 。 没有他们,你可能有一些部署问题问题作为Java运行时JAR(jfxrt.jar)不会自动对jdk7u7 java的引导类路径。 用户可以手动将其添加到他们的运行时类路径,但它可能是一个有点疼痛。 在今后的JDK版本(也许jdk7u10或jdk8),jfxrt.jar将在类路径中。 即使是这样,仍然会推荐使用JavaFX的包装工具,因为这将是确保您的部署包将在最兼容的方式工作的最佳途径。

该SwingInterop NetBeans项目是一个示例NetBeans项目,它利用JavaFX的部署工具,适用于秋千项目嵌入JavaFX组件。 来源SwingInterop是金JDK 7和JavaFX演示和示例下载。



文章来源: Playing audio using JavaFX MediaPlayer in a normal Java application?