Multithreading JavaFx ProgressBar不';t更新

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 {

我试图了解如何在多线程环境中更新ProgressBar。我在这里做错了什么,但我不知道是什么。这只需每隔3秒填满一次,但不会:

    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();