【发布时间】:2012-06-09 19:04:43
【问题描述】:
我想要一种非常简单的方法来从 Java 应用程序播放 mp3 文件。经过一番研究,我发现最新版本的 Java 7 SE 是用 JavaFX 打包的,所以我想我会尝试一下。这个问题不是关于播放 mp3 文件,而是关于让 JavaFX 以一种良好的方式工作。
因此,在我对 JavaFX 的第一次实验中,我使用了在 stackoverflow (see here) 的帖子中建议的一些代码,并创建了以下测试程序:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
public class progtest extends Application
{
/*---------------------------------------------------------*\
FUNCTION: main()
\*---------------------------------------------------------*/
public static void main(String args[])
{
launch(args);
} /* END: main() */
/*---------------------------------------------------------*\
FUNCTION: start()
\*---------------------------------------------------------*/
@Override
public void start(Stage stage)
{
Media medMsg
=
new Media(getClass().getResource("msg.mp3").toExternalForm());
MediaPlayer medplMsg = new MediaPlayer(medMsg);
medplMsg.play();
System.out.println("Here.\n");
} /* END: start() */
}
(这比我原来的测试程序稍微复杂一点:这个版本是在jewelsea 提出的建议之后提出的,以回应我之前发布的关于让程序运行的问题(see here)。)
为了编译我使用的这段代码:
javac -cp "c:\Program Files\Oracle\JavaFX 2.1 Runtime\lib\jfxrt.jar";..\bin -d ..\bin ..\src\progtest.java
为了运行代码,我进入了我的 ..\bin 目录并使用了:
java -cp .;"c:\Program Files\Oracle\JavaFX 2.1 Runtime\lib\jfxrt.jar" progtest
此程序运行并播放剪辑播放。但是,除非我按 Ctrl-C,否则程序不会返回到命令提示符。
这种行为似乎是某种线程问题。我已经多次看到这种行为与 Java 线程一起使用(遗憾的是,在允许程序优雅退出时存在真正的问题)。
所以,我想,也许如果我将代码放在它自己的线程中,然后在该线程结束时结束程序的主线程,一切都会好起来的。 (我可以看出这并不完全是一个有说服力的想法,但无论如何,我想我会尝试。)所以,我编写了以下代码的第二个版本:
这里是主线程:
import javafx.application.Application;
import javafx.stage.Stage;
import Msg.*;
public class progtest2 extends Application
{
/*---------------------------------------------------------*\
FUNCTION: main()
\*---------------------------------------------------------*/
public static void main(String args[])
{
launch(args);
} /* END: main() */
/*---------------------------------------------------------*\
FUNCTION: start()
\*---------------------------------------------------------*/
@Override
public void start(Stage stage)
{
Msg msgTime = new Msg();
msgTime.passClass(getClass());
msgTime.start();
try
{
msgTime.join();
}
catch (InterruptedException e)
{
}
System.out.println("Here.\n");
} /* END: start() */
}
下面是实际播放 mp3 文件的 Msg 线程的代码:
package Msg;
import KeyIO.*;
import javafx.application.Application;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
public class Msg extends Thread
{
private Class classRt = null;
/*--------------------------------------------------------*\
FUNCTION: passClass()
\*--------------------------------------------------------*/
public void passClass(Class rt)
{
classRt = rt;
} /* END: passClass() */
/*--------------------------------------------------------*\
FUNCTION: run()
\*--------------------------------------------------------*/
public void run()
{
Media medMsg
= new Media(classRt.getResource("msg.mp3").toExternalForm());
MediaPlayer medplMsg = new MediaPlayer(medMsg);
medplMsg.play();
System.out.println("Leaving Msg thread.\n");
} /* END: run() */
}
(我使用与上述相同的命令(比照文件名和类名)构建和运行这些文件。)
程序运行并播放 mp3 文件。在您听到文件之前,您会看到“Leaving Msg thread”。然后是“Here.”,如您所见,它分别来自 Msg 线程和主线程。但是,同样,程序并没有结束。我必须按 Ctrl-C 才能返回命令提示符。
我在主线程的末尾放了一个 System.exit() 调用,只是为了看看行为会是什么。行为是没有听到剪辑。似乎 System.exit() 调用在播放剪辑之前结束了进程。
所以,接下来我尝试将以下几行放在 System.out.println("Here.\n"); 之间以及我进行的 System.exit() 调用:
System.out.print("Press ENTER to end...");
KeyIO.ReadLine();
(KeyIO是我做的一个类,只是简单的做键盘输入输出,细节在这里不重要。)
我认为这只会阻止主线程继续前进,直到播放剪辑。
但是,没有。相反,该剪辑没有播放。当我按 ENTER 时,程序退出而不播放剪辑。
好的,现在我保留了键盘输入阻止代码,但我取消了 System.exit() 调用。现在音频片段播放了,但程序没有再次结束。
啊!
任何想法如何优雅地让它以一种显而易见的方式工作?我只想打电话播放剪辑,然后我希望能够结束程序。
提前谢谢你!
【问题讨论】:
标签: java multithreading javafx-2 exit