Multithreading JavaFx ProgressBar不';t更新
我试图了解如何在多线程环境中更新ProgressBar。我在这里做错了什么,但我不知道是什么。这只需每隔3秒填满一次,但不会:Multithreading JavaFx ProgressBar不';t更新,multithreading,progress-bar,javafx,Multithreading,Progress Bar,Javafx,我试图了解如何在多线程环境中更新ProgressBar。我在这里做错了什么,但我不知道是什么。这只需每隔3秒填满一次,但不会: Task<Void> task = new Task<Void>(){ @Override public Void call(){ for (int i = 1; i < 10; i++) { try {
Task<Void> task = new Task<Void>(){
@Override
public Void call(){
for (int i = 1; i < 10; i++) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
updateProgress(i , 10);
}
return null;
}
};
updProg = new ProgressBar();
updProg.progressProperty().bind(task.progressProperty());
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
Task Task=新任务(){
@凌驾
公开作废通知(){
对于(int i=1;i<10;i++){
试一试{
睡眠(3000);
}捕捉(中断异常e){
e、 printStackTrace();
}
系统输出打印LN(i);
更新进程(i,10);
}
返回null;
}
};
updProg=新进度条();
updplog.progressProperty().bind(task.progressProperty());
线程th=新线程(任务);
th.setDaemon(true);
th.start();
我遗漏了什么?你的样品对我来说很好 样品每3秒填充一点,半分钟内完全填充 我只是将它包装在一些脚手架代码中以使其可执行,并且它在没有更改的情况下工作(java7u15,win7)
导入javafx.application.application;
导入javafx.concurrent.Task;
导入javafx.scene.*;
导入javafx.scene.control.*;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
公共类ProgressTest扩展了应用程序{
公共静态void main(字符串[]args){Application.launch(args);}
@覆盖公共无效开始(阶段){
任务=新任务(){
@重写公共无效调用(){
对于(int i=0;i<10;i++){
试一试{
睡眠(100);
}捕捉(中断异常e){
Thread.interrupted();
打破
}
系统输出打印项次(i+1);
updateProgress(i+1,10);
}
返回null;
}
};
ProgressBar updProg=新的ProgressBar();
updplog.progressProperty().bind(task.progressProperty());
线程th=新线程(任务);
th.setDaemon(true);
th.start();
StackPane布局=新建StackPane();
布局。设置样式(“-fx背景色:玉米丝;-fx填充:10;”);
layout.getChildren().add(updProg);
舞台场景(新场景(布局));
stage.show();
}
}
也许您一直在使用Java 8的早期access版本,该版本在ProgressBar更新方面有一个bug(现已修复)
您是否使用最新的JDK 8早期访问?如果是,请参阅我提交的错误报告: 基本上,在早期access构建的最新版本中,他们对皮肤和css进行了一些更改。这导致一个隐藏的错误被暴露,其中子节点比父节点脏,但都需要在同一脉冲中重新绘制,父节点的脏级别最终覆盖子节点的脏级别 这会导致进度不显示,事实上,对我来说,
progressBar
在从任务调用updateProgress
后就完全不可见了。他们有一个补丁,我不知道什么时候能通过
一种解决方法,或者在等待补丁时使用jdk7,或者您可以像我所做的那样将旧css中的内容应用到您的css样式表中:
/*hack to get progress bar working. From: JDK7u17 jfxrt.jar!/com/sun/javafx/scene/control/skin/caspian/caspian.css */
/*******************************************************************************
* *
* ProgressBar *
* *
******************************************************************************/
.progress-bar {
-fx-skin: "com.sun.javafx.scene.control.skin.ProgressBarSkin";
-fx-background-color:
-fx-box-border,
linear-gradient(to bottom, derive(-fx-color,30%) 5%, derive(-fx-color,-17%));
-fx-background-insets: 0, 1;
-fx-indeterminate-bar-length: 60;
-fx-indeterminate-bar-escape: true;
-fx-indeterminate-bar-flip: true;
-fx-indeterminate-bar-animation-time: 2;
-fx-focus-traversable: true;
}
.progress-bar .bar {
-fx-background-color:
-fx-box-border,
linear-gradient(to bottom, derive(-fx-accent,95%), derive(-fx-accent,10%)),
linear-gradient(to bottom, derive(-fx-accent,38%), -fx-accent);
-fx-background-insets: 0, 1, 2;
-fx-padding: 0.416667em; /* 5 */
}
.progress-bar:indeterminate .bar {
-fx-background-color: linear-gradient(to left, transparent, -fx-accent);
}
.progress-bar .track {
-fx-background-color:
-fx-box-border,
linear-gradient(to bottom, derive(-fx-color,-15%), derive(-fx-color,2.2%) 20%, derive(-fx-color,60%));
-fx-background-insets: 0, 1;
}
.progress-bar:disabled {
-fx-opacity: 1.0
}
如果在FXML文件中定义了UPDPLOG,那么问题可能是这里的初始化 尝试删除此行:
updProg = new ProgressBar();
Timeline updateProgressBar=新的时间线(新的关键帧(持续时间.秒(1),新的EventHandler()){
@凌驾
公共无效句柄(ActionEvent事件){
/*其中秒和总秒是计数器和总秒数
分别放在秒++或
但是您希望更新进度。此时间线
每秒钟都会重新开始*/
progressBar.setProgress(秒/总秒);
}
}));
updateProgressBar.setCycleCount(Timeline.unfinite);
updateProgressBar.play();
我复制了你的代码,它运行得非常完美。我把它整合错了吗?我在一个子类中使用它,并且必须以静态方式访问progressbar。这会引起一些麻烦吗?我使用的是7v17 BTW RT-29018的修复程序将在未来几周内提供。也许你应该在循环条件中添加“=”,以便进度条可以在最后填充。是的,巴德,我刚刚复制并粘贴了问题中的代码,我不认为我等了大约30秒才看到进度条没有填充。我将循环更改为使用基于零的循环,而不是非标准的基于1的循环。我还设置了适当的处理,以防线程被中断。谢谢你的回答。问题是我实际上在使用jre 7v17。在win7和ubuntu中进行了测试,但没有成功。但jewelsas答案中的确切例子效果很好。这一定与我如何实施ProgressBar有关。如果有人否决了投票,请留下评论,这样海报就可以更正他的答案,并获得投票权。
updProg = new ProgressBar();
Timeline updateProgressBar = new Timeline(new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
/*Where Seconds and TotalSeconds are counter and total
respectively, also put somewhere Seconds++ or
however you want to update progress. This time line
will reapit each second */
progressBar.setProgress(Seconds / TotalSeconds);
}
}));
updateProgressBar.setCycleCount(Timeline.INDEFINITE);
updateProgressBar.play();