我想要一個真正簡單的方法來播放來自Java應用程序的mp3文件。經過一番研究,我發現最新版本的Java 7 SE與JavaFX一起打包,所以我想我會試試。這個問題不是關於播放mp3文件,而是關於讓JavaFX以一種行爲良好的方式工作。JavaFX 2.1和線程? - 或者 - 優雅地結束JavaFX應用程序?
所以,在我的第一個實驗中使用JavaFX,我使用了一些代碼,在後建議計算器(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文件的代碼:
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文件。在您聽到該文件之前,您會看到「離開消息線程」。然後「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()調用。現在播放了音頻剪輯,但程序沒有再次結束。
Urgh!
任何想法如何優雅地得到它的工作方式,它是明顯的一種會希望它的工作?我只想打個電話來播放剪輯,然後我想能夠結束該節目。
預先感謝您!
非常好!它像一個魅力。我將在下面發佈整個代碼。謝謝你jewelsea!很有幫助。它給了我很多關於我如何能夠在未來自己找出這些東西的見解。謝謝。 –