我在JavaFX上写程序,它必须显示窗口,播放视频,播放后隐藏窗口,并在随机时间后再次重复此操作。我需要知道如何在媒体播放器完成播放当前视频时进行随机延迟。我的想法是这些-如果通过在player.play()
后添加scene.hide()
,在播放完成前隐藏窗口,接下来播放器在另一个线程中工作。但是如果我在player.play()
命令后通过TimeUnit.SECONDS.sleep(10)
添加延迟,视频播放将在10秒后开始。请解释一下,实际发生了什么,以及如何在播放完成后添加延迟。
我的代码:
import java.io.File;
import java.lang.management.ManagementFactory;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.scene.input.KeyCombination;
import java.util.concurrent.TimeUnit;
public class Main extends Application implements Runnable {
private String Dir = System.getProperty("./");
private Stage stage;
private boolean fl;
public static void main(String[] args) throws Exception{
launch(args);
}
public void run() { //if playing is complete - hide window
//System.out.printf("Media player thread is %d \n",Thread.currentThread().getId());
this.stage.hide();
}
private static int randomIntBetween(int first, int last) {
int rnd_int= (int)(first + Math.round(Math.random()*Math.abs((last-first))));
return rnd_int;
}
@Override
public void start(Stage stage) throws Exception {
this.stage=stage;
String[] video_paths = {"lp.mp4","sc_1.mp4"};
stage.setFullScreen(true);
stage.setFullScreenExitHint("");
stage.setFullScreenExitKeyCombination(javafx.scene.input.KeyCombination.NO_MATCH);
while (true){
String video_path = video_paths[randomIntBetween(0,video_paths.length-1)];//Get random video (path)
File f = new File(video_path);
Media media = new Media(f.toURI().toURL().toString());
javafx.scene.media.MediaPlayer player = new javafx.scene.media.MediaPlayer(media);
MediaView viewer = new MediaView(player);
//change width and height to fit video
DoubleProperty width = viewer.fitWidthProperty();
DoubleProperty height = viewer.fitHeightProperty();
width.bind(Bindings.selectDouble(viewer.sceneProperty(), "width"));
height.bind(Bindings.selectDouble(viewer.sceneProperty(), "height"));
viewer.setPreserveRatio(true);
StackPane root = new StackPane();
root.getChildren().add(viewer);
//set the Scene
Scene scenes = new Scene(root);
stage.setScene(scenes);
player.setOnEndOfMedia(this);
//System.out.printf("Main thread is %d \n",Thread.currentThread().getId());
stage.show();
player.play();
//this.stage.hide();
//TimeUnit.SECONDS.sleep(randomIntBetween(3,100);
break;//added for single iteration
}
}
}
如果我在www.example.com()后面加上break,我的代码就可以工作player.play了。但这并不能解决我的问题。
1条答案
按热度按时间oyt4ldly1#
不幸的是,你的方法是完全错误的。你的方法中有一些主要的错误和误解,还有一些小的改进可以在你的代码中进行。
主要问题:
1.你不需要(也不应该)创建另一个线程来暂停,使用
PauseTransition
。1.永远不要让JavaFX线程休眠。
1.您应该 * 永远不要 * 从JavaFX线程以外的任何线程修改Scene Graph或Stages中节点的属性。
PauseTransition.onFinished
),而不是代码循环。1.永远不要在JavaFX线程上循环-GUI中不会发生任何事情。
其他改进:
1.应用程序应该只对应用程序生命周期负责。
1.应用程序不应实现runnable。
1.要获取工作目录,请使用system property "user.dir"。
1.不要写一个函数来获取范围内的随机整数,使用内置的库函数。
1.关注naming conventionsalways。
1.对于大多数应用程序来说,设置一个不匹配的键和全屏退出的提示似乎是一个坏主意。
1.不要定义像名称错误的
Dir
这样的变量,因为您从来没有使用过它。1.代码应为properly formatted。
1.绑定到属性,而不是你使用的奇怪的绑定选择方案,例如,你可以写
viewer.fitWidthProperty().bind(scene.widthProperty())
。1.但是,不要使用绑定进行布局,使用带有最少适当布局提示的布局窗格。
1.不要在代码中不必要地使用完全限定名,而是添加适当的import语句。
相关: