有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在现有Swing项目中使用JavaFX的MediaPlayer

我有一个用Swing编写的应用程序,其中我想使用JavaFX的MediaPlayer来播放音频/声音文件

这是主文件的压缩版本:

class MyApp
{
   private MyApp myApp;
   private JFrame myFrame;
   private Media media;
   private MediaPlayer mediaPlayer;
   public static void main(String[] args)
   {
      Runnable thread = new Runnable()
      {
         public void run()
         {
             myApp = new MyApp();
         }          
      };
      SwingUtilities.invokeLater(thread);
  }
  public void MyApp()
  {
    //this is called by SwingUtilities.invokeLater();

    URL url = //getting URL to a sound file stored locally//;
    media = new Media(url.toString() );
    mediaPlayer = new MediaPlayer( media );                        
    mediaPlayer.play();

    myFrame = new JFrame(); //building swing UI here
  }

这似乎在Netbeans中起作用。但是,当Netbeans构建。jar,我试着运行。jar,我得到了一个错误日志文件。包含一些内存/线程错误的jar目录

我是否需要使用Platform.runLater()方法来实现这一点?或者我还有什么做错的吗


共 (1) 个答案

  1. # 1 楼答案

    当与嵌入Swing应用程序中的JavaFX控件交互时,一定要在Platform.runLater调用中进行,而不是在Swing.invokeLater调用中进行

    您还应该确保JavaFX系统已初始化,并且(最好)使用本文中提到的JavaFX打包工具对应用程序进行了打包:Playing audio using JavaFX MediaPlayer in a normal Java application?

    虽然在JavaFX线程下运行一些创建JavaFX控件的代码对大多数控件都有效,甚至有时与某些控件的一些交互似乎也能在JavaFX线程下工作,但在实践中,我发现这样做不值得冒风险,并且可能会遇到模糊的错误或竞争条件。JavaFX设计时考虑到了UI,因此最好使用Platform.runLater之类的工具保持这种方式。Swing的事件调度线程也是如此。您需要将这两个框架之间的线程交互分开

    看看你问题中MyApp代码中的5行代码,我有以下建议

    无论在哪个线程上执行,因为它不与任何框架交互:

    URL url = //getting URL to a sound file stored locally//;
    

    利用JavaFX控件做的应该包装在平台上。runLater:

    media = new Media(url.toString() );
    mediaPlayer = new MediaPlayer( media );                        
    mediaPlayer.play();
    

    与Swing框架交互,因此应该包装在Swing.invokeLater中:

    myFrame = new JFrame(); //building swing UI here
    

    注意:仅仅一个runLater调用是不够的,您还需要在MediaPlayer play调用之后从runLater主体内部调用Swing jframe调用