2012-12-14 14 views
2

J'essaie de montrer la progression et le statut de chaque tâche dans le JavaFXTableView. Chaque tâche représente par une ligne dans un TableView.JavaFX TableView ne met pas à jour

enter image description here

Chaque tâche est exécutée dans un thread séparé. Tâche peut être comme - téléchargement de fichiers à partir du serveur, copier des fichiers d'un compte à un autre compte, etc. Threads peut prendre beaucoup de temps pour terminer la tâche. Mon application contrôle également le nombre de threads à exécuter en file d'attente. Avec le réglage par défaut, il peut exécuter 5 threads maximum à la fois.

Mon problème est - Mon TableView n'affiche pas le statut mis à jour et la progression. Je dois cliquer sur les en-têtes de colonne pour actualiser le TableView. Comment faire pour mettre à jour TableView aromatiquement? En arrière-plan, si je lance un thread qui se déclenche automatiquement après un intervalle de temps spécifique pour rafraîchir le TableView faisant de mon UI geler.

L'exemple ne montre pas exactement ce que je fais dans mon application mais j'ai essayé de montrer à quel problème je suis confronté. Lorsque vous exécutez le programme, vous verrez le TableView avec deux colonnes 1. Nom et 2. Progrès. Au démarrage, le nom sera "Avant" pour chaque ligne alors que vous verrez la barre de progression en cours d'exécution. J'ai ajouté un délai d'une seconde à la mise à jour des valeurs de cellules et à l'arrêt de la barre de progression.

import java.util.logging.Level; 
import java.util.logging.Logger; 
import javafx.application.Application; 
import javafx.beans.property.DoubleProperty; 
import javafx.beans.property.SimpleDoubleProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.ProgressBarTableCell; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.StackPaneBuilder; 
import javafx.stage.Stage; 

public class UpdateTableView extends Application { 

    private TableView<Person> personTable = new TableView<>(); 
    private TableColumn colName = new TableColumn<>("Name"); 
    private TableColumn colProgressBar = new TableColumn("Progress Bar"); 

    @Override 
    public void start(Stage primaryStage) { 
     showDialog(primaryStage); 

     colName.setCellValueFactory(new PropertyValueFactory("name")); 
     colProgressBar.setCellValueFactory(new PropertyValueFactory("progressBar")); // "name" here is for just to render the column 
     colProgressBar.setCellFactory(ProgressBarTableCell.forTableColumn()); 
     personTable.getColumns().addAll(colName, colProgressBar); 

     for (int i = 0; i < 10; i++) { 
      Person person = new Person(); 
      person.setProgressBar(-1.0); 
      person.setName("Before" + i); 
      personTable.getItems().add(person); 
     } 


     Thread threadAction1 = new Thread() { 
      public void run() { 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(UpdateTableView.class.getName()).log(Level.SEVERE, null, ex); 
       } 
       ObservableList<Person> items = personTable.getItems(); 
       for (int i = 0; i < items.size(); i++) { 
        Person person = items.get(i); 
        person.setName("After" + i); 
        person.setProgressBar(0.0); 
       } 
      } 
     }; 
     threadAction1.start(); 
    } 

    public void showDialog(Stage primaryStage) { 
     try { 
      StackPane root = StackPaneBuilder.create().children(personTable).build(); 
      primaryStage.setScene(new Scene(root, 300, 250)); 
      primaryStage.show(); 
     } catch (Exception ex) { 
      System.out.println("Exception caught while showing dialog" + ex.getMessage()); 
     } 
    } 

    public static class Person { 

     private StringProperty name; 

     public void setName(String name) { 
      this.name = new SimpleStringProperty(name); 
     } 
     private DoubleProperty progressBar; 

     private Person() { 
     } 

     public double getProgressBar() { 
      return progressBar.get(); 
     } 

     public void setProgressBar(double surname) { 
      this.progressBar = new SimpleDoubleProperty(surname); 
     } 

     public Person(String name, double surname) { 
      this.name = new SimpleStringProperty(name); 
      this.progressBar = new SimpleDoubleProperty(surname); 

     } 

     public String getName() { 
      return name.get(); 
     } 

     public StringProperty nameProperty() { 
      return name; 
     } 

     public DoubleProperty progressBarProperty() { 
      return progressBar; 
     } 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

Répondre

4

Vous devez mettre à jour votre Person classe comme indiqué ci-dessous:

public static class Person { 

    private StringProperty name; 
    private DoubleProperty progressBar; 

    private Person() { 
     name = new SimpleStringProperty(); 
     progressBar = new SimpleDoubleProperty(); 
    } 

    public Person(String name, double surname) { 
     this.name = new SimpleStringProperty(name); 
     this.progressBar = new SimpleDoubleProperty(surname); 
    } 

    public void setName(String name) { 
     this.name.set(name); 
    } 

    public double getProgressBar() { 
     return progressBar.get(); 
    } 

    public void setProgressBar(double surname) { 
     this.progressBar.set(surname); 
    } 

    public String getName() { 
     return name.get(); 
    } 

    public StringProperty nameProperty() { 
     return name; 
    } 

    public DoubleProperty progressBarProperty() { 
     return progressBar; 
    } 
} 

dans setter méthodes que vous créez nouvel objet de name & progressbar chaque fois, de sorte que TableView ne reçoit pas la mise à jour.