3

我有一个用 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()方法才能使其正常工作?还是我做错了什么?

4

1 回答 1

4

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

您还应该确保 JavaFX 系统已初始化,并且(最好)使用本文中提到的 JavaFX 打包工具对应用程序进行确认:在普通 Java 应用程序中使用 JavaFX MediaPlayer 播放音频?.

虽然运行一些在 JavaFX 线程之外创建一些 JavaFX 控件的代码适用于大多数控件,甚至与某些控件的某些交互有时似乎在 JavaFX 线程之外工作,但实际上我发现它不值得冒风险,并且可能会掩盖错误或竞争条件这样做的时候可能会遇到。JavaFX 在设计时考虑了 UI 的单线程交互模型,因此最好使用Platform.runLater. Swing 的事件调度线程也是如此。您需要将这两个框架之间的线程交互分开。

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

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

   

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

使用 JavaFX 的控件确实应该包装在 Platform.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调用。

于 2012-09-23T04:54:46.107 回答