java - JavaFX Thread Freezing GUI -
i'm still new threading, , i'm working javafx first time, double whammy! main issue threading, believe. wanting crossfade 2 mediaplayer audios on skip button. so, believe created thread crossfade audios on 2 seconds, , should end thread. that's "think" i'm doing. however, when program runs, freezes after second skip. of code i'm using javafx tutorials , works intended before tried crossfade. advice put great use, tia! crossfade class:
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 (int = 0; < 20; ++) { 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 sleep on xfade"); e.printstacktrace(); } } mp1.stop(); //this.interrupt(); } } audio class:
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(); } } code skip button:
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 crossfade in audio class (supposed start thread) audio.crossfade(curplayer,nextplayer); //these "old" stop , play calls media //curplayer.stop(); //nextplayer.play(); } });
in general, shouldn't change that's part of ui outside fx application thread. haven't worked mediaplayers, believe play same rules.
you can simplify lot using animation api. pausetransition can used manage each pause, , can "play" these in sequence using sequentialtransition. manage threading you. (this not tested...)
public class audio{ public static void crossfade(mediaplayer mp1, mediaplayer mp2) { double currentvol = mp1.getvolume(); mp2.setvolume(0); mp2.play(); sequentialtransition crossfade = new sequentialtransition(); (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(); } } of course, if you're going use animation api, may use in way "smoothly", instead of in discrete steps:
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(); } } update: if still using javafx 2.2, replace lambda expression (crossfade.setonfinished(event -> mp1.stop());) inner class:
crossfade.setonfinished(new eventhandler<actionevent>() { @override public void handle(actionevent event) { mp1.stop(); } }); you need declare mp1 final:
public static void crossfade(final mediaplayer mp1, final mediaplayer mp2) { ... }
Comments
Post a Comment