Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在普通Java应用程序中使用JavaFXMediaPlayer播放音频?_Java_Audio_Javafx 2 - Fatal编程技术网

在普通Java应用程序中使用JavaFXMediaPlayer播放音频?

在普通Java应用程序中使用JavaFXMediaPlayer播放音频?,java,audio,javafx-2,Java,Audio,Javafx 2,我需要能够在一个普通的Java项目中播放音频文件(MP3/Wav)。我更喜欢使用新的JavaFXMediaPlayer而不是JMF。我编写了一些代码来测试这一点: public void play() { URL thing = getClass().getResource("mysound.wav"); Media audioFile = new Media( thing.toString() ); try {

我需要能够在一个普通的Java项目中播放音频文件(MP3/Wav)。我更喜欢使用新的JavaFXMediaPlayer而不是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);
    }        
}
当我运行这个时,我得到一个异常:Toolkit未初始化

我知道这与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)
java.lang.IllegalStateException:工具包未初始化
位于com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:121)
位于com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:116)
位于javafx.application.Platform.runLater(Platform.java:52)
位于javafx.scene.media.MediaPlayer.init(MediaPlayer.java:445)
在javafx.scene.media.MediaPlayer。(MediaPlayer.java:360)
在javaapplication6.javaapplication6.play(javaapplication6.java:23)
在javaapplication6.javaapplication6.main(javaapplication6.java:14)

用于在Swing中集成JavaFX MediaPlayer的解决方案

请使用,并注意仅在JavaFX线程上以及JavaFX系统正确初始化后使用JavaFX对象

JavaFX是普通的Java,这让问题有点混乱,但我猜你指的是Swing

这是一个从Swing启动的音频播放器示例。此示例假定Windows 7的默认公共示例音乐文件夹(C:\Users\public\music\sample music)中有一组mp3文件,并依次播放每个文件

JavaFXMediaPlayerLaunchedFromSwing.java

这段代码负责创建一个Swing应用程序,该应用程序反过来初始化JavaFXToolkit并在JavaFX应用程序线程上创建JavaFX场景

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

创建一个JavaFX媒体播放器,该播放器按顺序播放给定文件夹中的所有
.mp3
媒体文件。它为媒体提供一些控件(播放、暂停、跳过曲目、当前曲目播放进度指示器)

后续问题的答案

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

注:本后续答复中关于包装的信息可能已注明日期,此时存在其他首选包装选项(例如)

从技术上讲,Swing不构建Jar文件,但javafx打包命令的Jar可以构建

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


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

是第14行
媒体音频文件=新媒体(thing.toString())
?@andrewhompson否,这是在调用
play()
方法的主方法中。第23行是这一行<代码>媒体播放器=新媒体播放器(音频文件)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; } }
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();
    }
}