java - Java(FX) 在播放一种声音时,播放另一种声音
问题描述
我有一个 FX 应用程序,它从一开始就开始播放音乐,这很有效。现在,当我打开一种在其上播放另一种声音的方法时,我想要它。
我像第一个一样编码了第二个声音,但它不起作用。我试着做一个新的Thread
但没有改变。新声音实际上以某种方式播放。有时它根本不播放。有时完全,有时只是一秒钟。
新声音的方法
public void showFight(int fighterLeft, int fighterRight) throws InterruptedException {
//Some code
new Thread(() -> {
music2();
}).start();
new Thread(() -> {
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
}
Platform.runLater(() -> {
//FadeIn();
FightPane.setVisible(false);
});
}).start();
}
public static void music2() {
Media hit2 = new Media(JavaFXApplicationStratego.class.getResource("/Sounds/fight.mp3").toString());
MediaPlayer mediaPlayer2 = new MediaPlayer(hit2);
mediaPlayer2.play();
}
第一声
public static void music() {
String bip = "/stopen.mp3";
Media hit = new Media(JavaFXApplicationStratego.class.getResource("/Sounds/stopen.mp3").toString());
MediaPlayer mediaPlayer = new MediaPlayer(hit);
mediaPlayer.play();
}
解决方案
您没有保持对MediaPlayer
. 这意味着一旦调用#music()
返回,实例就有资格进行垃圾收集(同样的问题 wrt #music2()
)。一旦垃圾收集,媒体将停止播放。由于垃圾收集周期不是在预定时间发生,而是在需要时发生,因此您会看到应用程序的不同实例之间的不同行为。解决方法是将MediaPlayer
实例存储在它们将是强可达的地方,例如在你的类的一个字段中(假设你的类的实例也是强可达的)。
根据您在问题中提供的内容,也没有理由使用线程。在 JavaFX 中播放音乐已经是异步的。至于稍后在JavaFX 应用程序线程上执行操作,最好使用动画 API。JavaFX 定期后台任务问答展示了这方面的示例。例如:
PauseTransition pt = new PauseTransition(Duration.seconds(3));
pt.setOnFinished(e -> FlightPane.setVisible(false));
pt.play();
注意:假设FlightPane
是一个字段的名称,理想情况下应该命名为flightPane
. 请参阅Java 命名约定。
推荐阅读
- ios - 如何从包含特定标题的日历中获取事件?
- python - 我如何在没有终端命令的情况下运行 vscode
- javascript - 使用 React Router 根据 React 中的 JSON 返回值路由到特定视图
- mysql - 在mysql中保存base64字符串
- html - 向下滚动时,可以在我的侧边栏上方看到一个空格
- javascript - React useState() 数组未更新
- ansible - Ansible 和 Terraform 调试
- python - 使用 pandas groupby 计算列
- javascript - Fabric js 变换和缩放画布以适应视口中的所有对象
- python - (discord.py) 如何获取用户拥有多少权限的列表