[英]JavaFX thread should wait for background thread but without freezing the UI (JavaFX)
[英]JavaFX Thread Freezing GUI
我對線程技術還很陌生,而且我是第一次使用javaFX,所以這可能是雙重打擊! 我認為,我的主要問題是線程。 我想在“跳過”按鈕上淡入淡出兩個Mediaplayer音頻。 因此,我相信我創建了一個線程來淡化音頻兩秒鍾,然后結束線程。 這就是我“想”我正在做的事情。 但是,程序運行時,通常在第二次跳過后凍結。 我為javaFX使用的大多數代碼來自教程,並且在嘗試進行淡入淡出之前按預期工作。 任何建議都將得到充分利用,TIA! CrossFade課程:
import javafx.scene.media.MediaPlayer;
public class CrossFade extends Thread
{
private MediaPlayer mp1;
private MediaPlayer mp2;
private double currentVol;
public CrossFade(MediaPlayer mp1, MediaPlayer mp2)
{
this.mp1 = mp1;
this.mp2 = mp2;
currentVol = mp1.getVolume();
System.out.println("Vol: " + currentVol);
}
@Override
public void run() {
mp2.setVolume(0);
mp2.play();
//20 increments in volume, every 100ms
for (int i = 0; i < 20; i ++)
{
mp1.setVolume(mp1.getVolume()-currentVol/20);
mp2.setVolume(mp2.getVolume()+currentVol/20);
try
{
//sleep 100 ms
Thread.sleep(100);
}
catch (InterruptedException e)
{
System.out.println("Unable to sleep on xFade");
e.printStackTrace();
}
}
mp1.stop();
//this.interrupt();
}
}
音頻類別:
import javafx.scene.media.MediaPlayer;
public class Audio{
public static void crossfade(MediaPlayer mp1, MediaPlayer mp2)
{
Thread xFade = new Thread(new CrossFade(mp1,mp2));
xFade.start();
}
}
跳過按鈕的代碼:
skip.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent actionEvent) {
final MediaPlayer curPlayer = mediaView.getMediaPlayer();
MediaPlayer nextPlayer = players.get((players.indexOf(curPlayer) + 1) % players.size());
mediaView.setMediaPlayer(nextPlayer);
curPlayer.currentTimeProperty().removeListener(progressChangeListener);
//calls the crossfade in audio class (supposed to start that thread)
Audio.crossfade(curPlayer,nextPlayer);
//these were the "old" stop and play calls to the media
//curPlayer.stop();
//nextPlayer.play();
}
});
通常,您不應從FX Application Thread外部更改UI的一部分。 我與MediaPlayers的合作不多,但我相信他們的游戲遵循相同的規則。
您可以通過使用Animation API來簡化很多操作。 PauseTransition
可用於管理每個暫停,您可以使用SequentialTransition
依次“播放”這些暫停。 基本上,這將為您管理所有線程。 諸如此類(未經測試...)
public class Audio{
public static void crossfade(MediaPlayer mp1, MediaPlayer mp2)
{
double currentVol = mp1.getVolume();
mp2.setVolume(0);
mp2.play();
SequentialTransition crossfade = new SequentialTransition();
for (int i=0; i<20 i++) {
PauseTransition pause = new PauseTransition(Duration.millis(100));
pause.setOnFinished(event -> {
mp1.setVolume(mp1.getVolume()-currentVol/20);
mp2.setVolume(mp2.getVolume()+currentVol/20);
});
crossfade.getChildren().add(pause);
}
crossfade.setOnFinished(event -> mp1.stop());
crossfade.play();
}
}
當然,如果您要使用Animation API,則最好以“平穩”完成所有操作的方式使用它,而不是分步進行:
public class Audio {
public static void crossfade(MediaPlayer mp1, MediaPlayer mp2) {
final double currentVolume = mp1.getVolume();
mp2.setVolume(0);
mp2.play();
Timeline crossfade = new Timeline(new KeyFrame(Duration.seconds(2),
new KeyValue(mp1.volumeProperty(), 0),
new KeyValue(mp2.volumeProperty(), currentVolume)));
crossfade.setOnFinished(event -> mp1.stop());
crossfade.play();
}
}
更新:如果您仍在使用JavaFX 2.2,請使用內部類替換lambda表達式( crossfade.setOnFinished(event -> mp1.stop());
):
crossfade.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
mp1.stop();
}
});
您還需要將mp1
聲明為final
:
public static void crossfade(final MediaPlayer mp1, final MediaPlayer mp2) { ... }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.