2013-03-19 18 views
5

Próbuję zrozumieć, jak zaktualizować ProgressBar w środowisku wielowątkowym. Iam robi coś złego tutaj, ale nie widzę, co to jest. Powinno to po prostu wypełnić pasek co 3 sekundy, ale nie:JavaFx ProgressBar nie aktualizuje

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

Czego mi brakuje?

Odpowiedz

8

Twoja próbka działa dobrze dla mnie.

Próbka wypełnia pasek nieco co 3 sekundy, całkowicie wypełniając pasek w ciągu pół minuty.

Właśnie opakowałem to w pewien kod rusztowania, aby uczynić go wykonalnym i działało bez zmian (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(); 
    } 
} 

Może byliście przy użyciu niektórych wczesną wersję dostępu Javy 8, który miał błąd w nim (obecnie stały) wokół aktualizacjach ProgressBar.

RT-29018 ProgressBar and ProgressIndicator disappear when progressProperty is updated

+0

I skopiowany kod i działa po prostu doskonale. Czy w jakiś sposób go zinterpretowałem? Używam go w podklasie i mam dostęp do paska postępu w sposób statyczny. czy to może sprawić kłopoty? Im using 7v17 btw – Chromos

+0

edit: gui jest zaprojektowany w arkuszu fxml. – Chromos

+0

Czy łatka jest już dostępna @jewelsea? –

1

Używasz najnowszej JDK 8 Early Access? Jeśli tak, zobacz ten raport o błędzie, który zgłosiłem: http://javafx-jira.kenai.com/browse/RT-29018

Zasadniczo w najnowszej wersji kompilacji wczesnego dostępu dokonano pewnych zmian w skinach i css. Spowodowało to ujawnienie ukrytego błędu w węzłach potomnych, które są brudniejsze niż węzły nadrzędne, ale oba wymagają odświeżenia w tym samym impulsie, brudny poziom rodzica kończy się nadpisując brudny poziom węzłów potomnych.

Powoduje to, że postęp nie jest wyświetlany, a w rzeczywistości dla mnie progressBar stał się całkowicie niewidoczny, jak tylko updateProgress został wywołany z zadania. Mają łatkę na miejscu, nie wiem, kiedy to się skończy.

obejście, albo użyć jdk7 czekając na patcha, czy można zrobić to, co zrobiłem i zastosować ten ze starego CSS do swojego arkusza stylów 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 za odpowiedź. Rzecz polega na tym, że używam jre 7v17. Przetestował to w win7 i Ubuntu i nie zadziałał. Ale dokładny przykład odpowiedzi od jewelsa działał dobrze. Musi mieć coś do zrobienia, w jaki sposób zaimplementowałem ProgressBar – Chromos

0

Jeśli zdefiniowano updProg w Plik FXML, wtedy problem może być tutaj inicjalizacją.

try po prostu usunąć ten wiersz:

updProg = new ProgressBar(); 
+0

. Dlaczego w dół? – Chaiavi

+0

Proszę, jeśli ktoś głosuje, zachowaj komentarz na ten temat, aby plakat poprawił odpowiedź i mógł uzyskać awans. –

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