为什么此JavaFX播放器冻结? [英] Why is this JavaFX player freezing?

查看:62
本文介绍了为什么此JavaFX播放器冻结?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用以下播放器:

I'm trying to use the following player:

public class JavaFXPlayer extends Application {
  private MediaPlayer mediaPlayer;
  private Media media;

  public JavaFXPlayer(String strUrl) {
    this.media = new Media(strUrl);
  }
  public void play() {
    Application.launch();
  }
  @Override
  public void start(Stage primaryStage) throws Exception {
    mediaPlayer = new MediaPlayer(media);

    // by setting this property to true, the audio will be played
    mediaPlayer.setAutoPlay(true);
    primaryStage.setTitle("Playing Audio");
    primaryStage.show();
  }

  @Override
  public void stop() {
    if (mediaPlayer != null) {
      mediaPlayer.stop();
      mediaPlayer.dispose();
    }
  }
}

然后我像这样运行:

JavaFXPlayer player = new JavaFXPlayer(strUrl);
player.play();

但是,当我运行 player.play()时,我的整个程序立即冻结.为什么会这样?

However, my whole program freezes instantly when I run player.play(). Why is that?

推荐答案

通过 Application#launch 启动JavaFX应用程序时,运行时将为 Application 子类创建一个实例.通过反思你.这对实现施加了一些限制:

When launching a JavaFX application via Application#launch the runtime creates an instance of the Application subclass for you through reflection. This places some constraints on the implementation:

  • 它必须是 public 类.
  • 它必须具有一个 public ,无参数的构造函数.
  • 如果使用模块,则必须将其程序包至少导出到 javafx.graphics 模块.
  • It must be a public class.
  • It must have a public, no-argument constructor.
  • If using modules then its package must be exported to at least the javafx.graphics module.

如果将 Application 子类用作应用程序的主类,则不需要main方法-至少对于JavaFX 8-12 1 版本而言不需要.如果您有main方法,它应该看起来像这样:

If you use your Application subclass as the main class of the application then you don't need a main method—at least not for JavaFX versions 8-121. If you do have a main method it should look something like this:

public class MyApp extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception { ... }

}

您还可以将其他一些类的功能用作主类:

You could also have some other class function as the main class:

public class Main {

    public static void main(String[] args) {
        Application.launch(MyApp.class, args);
    }

}

无论选择哪种方式使用,都必须仍然有一个公共的,无参数的构造函数.这意味着您无法通过构造函数传递 Media URL.目前尚不清楚该URL来自何处.如果URL来自命令行参数,则可以从 Application 实例(例如,在 start(Stage) init()内部)访问这些URL.>)通过 Application#getParameters().如果网址是硬编码的,则只需要以不同的方式使用它即可(例如,直接在 Application 子类中使用).

Whichever you choose to use you must still have a public, no-argument constructor. This means you lose the ability to pass in the Media URL through the constructor. It's not clear where this URL is coming from either. If the URL is coming from the command line arguments then you can access those from the Application instance (e.g. inside start(Stage) or init()) via Application#getParameters(). If the URL is hard-coded you'll just have to use it differently (e.g. directly in the Application subclass).

所有这些,我不确定您的应用为何冻结,因为您没有提供最小的可复制示例.但是,调用 Application#launch 的线程在该方法调用中被阻塞,直到JavaFX运行时退出为止.这意味着如果您在上述线程上调用 JavaFX Application Thread ,则可能会阻塞该线程.

All that said, I'm not entirely sure why your application freezes as you did not provide a minimal reproducible example. However, the thread calling Application#launch is blocked in that method call until the JavaFX runtime exits. This means it's possible you're blocking the JavaFX Application Thread if you call that method on said thread.

1.JavaFX具有特殊的处理方式,只要主类是 Application 的实现,就可以省略main方法.但是,从版本11的JDK中删除JavaFX以后,可能会在以后的版本中删除此功能.

1. JavaFX has special treatment which allows the main method to be omitted so long as the main class is an implementation of Application. However, with the removal of JavaFX from the JDK in version 11, this functionality may be removed in a future release.

这篇关于为什么此JavaFX播放器冻结?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆