2013-03-19 123 views
5

我嘗試瞭解如何在多線程環境中更新ProgressBar。 Iam在這裏做錯了事,但我沒看到它是什麼。這應該簡單地填滿每3秒的酒吧,但它不:JavaFx ProgressBar不更新

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

我錯過了什麼?

回答

8

你的樣品適合我。

樣本每3秒就會有一點點填滿酒吧,在半分鐘內完全填滿酒吧。

我只是將它包裹在一些腳手架代碼中以使其可執行並且它沒有改變地工作(java7u15,win7)。

simpletaskprogress

import javafx.application.Application; 
import javafx.concurrent.Task; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class ProgressTest extends Application { 
    public static void main(String[] args) { Application.launch(args); } 
    @Override public void start(Stage stage) { 
    Task<Void> task = new Task<Void>() { 
     @Override public Void call() { 
     for (int i = 0; i < 10; i++) { 
      try { 
      Thread.sleep(100); 
      } catch (InterruptedException e) { 
      Thread.interrupted(); 
      break; 
      } 
      System.out.println(i + 1); 
      updateProgress(i + 1, 10); 
     } 
     return null; 
     } 
    }; 

    ProgressBar updProg = new ProgressBar(); 
    updProg.progressProperty().bind(task.progressProperty()); 

    Thread th = new Thread(task); 
    th.setDaemon(true); 
    th.start(); 

    StackPane layout = new StackPane(); 
    layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;"); 
    layout.getChildren().add(updProg); 

    stage.setScene(new Scene(layout)); 
    stage.show(); 
    } 
} 

也許你一直在使用Java 8的一些早期版本的訪問其中有在它周圍進度更新的錯誤(現已修復)。

RT-29018 ProgressBar and ProgressIndicator disappear when progressProperty is updated

+0

我複製你的代碼,它運行得非常完美。不知怎的,我整合了它嗎?我在一個子類中使用它,並且必須以靜態方式訪問進度條。這會造成一些麻煩嗎?我使用7v17 btw – Chromos 2013-03-20 12:18:07

+0

編輯:gui是在fxml表中設計的。 – Chromos 2013-03-20 12:24:32

+0

補丁已經可用了@jewelsea? – 2013-03-21 09:11:55

1

您是否使用了最新的JDK 8早期訪問?如果是這樣,請參閱我提交的這個錯誤報告:http://javafx-jira.kenai.com/browse/RT-29018

基本上,在最近發佈的早期訪問版本中,他們對皮膚和css做了一些更改。這導致了一個隱藏的bug,其中哪個子節點比父節點髒,但都需要在同一個脈衝中重繪,父級的髒級別最終會覆蓋子節點的髒級別。

這會導致進度不顯示,事實上,對於我而言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 
} 
+0

thx爲您的答案。事情是我實際使用jre 7v17。在win7和ubuntu上測試過,並沒有工作。但從jewelsas的答案確切的例子工作得很好。它必須要做些什麼來實現ProgressBar – Chromos 2013-03-21 11:38:58

0

如果您在定義updProg FXML文件,那麼問題可能是這裏的初始化。

嘗試只是刪除這一行:

updProg = new ProgressBar(); 
+0

爲什麼downvote? – Chaiavi 2016-03-23 10:31:26

+0

如果有人不滿意,請留下評論,這樣海報可以糾正他的答案,並可以得到upvote。 – 2016-05-03 20:49:03

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