2017-10-10 1 views
-1

J'ai récemment rencontré un problème intéressant. J'ai une table avec 1 int et 3 colonnes String. J'ai implémenté le filtrage pour la table qui fonctionne parfaitement bien sauf un point mineur: Chaque fois qu'il y a au moins un résultat filtré (mais moins que la quantité de lignes visibles), la colonne int affiche des valeurs nulles comme valeurs pour les lignes vides. Si le nombre de correspondances trouvées est cependant supérieur au nombre visible de lignes, aucune valeur nulle n'est ajoutée (même avec la fonctionnalité de défilement). Ceci est décrit le mieux avec les images:JavaFX TableView affiche des valeurs nulles

with null values

Filtre pour valeur non-existante ne présente pas les valeurs NULL:

without null values

Le code pour le filtrage:

FilteredList<Word> filteredData = new FilteredList<>(masterData,e->true); 
    SortedList<Word> sortedData = new SortedList<>(filteredData); 
    sortedData.comparatorProperty().bind(table.comparatorProperty()); 
    table.setItems(sortedData); 
    TextField filter = new TextField(); 
    filter.setPromptText("Filter"); 
    filter.textProperty().addListener((observableValue,oldValue,newValue)->{ 
     filteredData.setPredicate((Predicate<? super Word>) word->{ 
      if(word.getAllCz().toLowerCase().contains(newValue.toLowerCase()))return true; 
      else if(word.getAllEng().toLowerCase().contains(newValue.toLowerCase()))return true; 
      else if(String.valueOf(word.getUnitNo()).equals(newValue))return true; 
      else return false; 
     }); 
    }); 

CellValue usine:

column.setCellValueFactory(new PropertyValueFactory<>(data)); 
    column.setCellFactory(tc-> { 
     TableCell<Word, Integer> cell = new TableCell<>(); 
     Text text = new Text(); 
     cell.setGraphic(text); 
     text.setTextAlignment(TextAlignment.CENTER); 
     text.setStyle("-fx-fill: -fx-text-background-color;"); 
     text.setFontSmoothingType(FontSmoothingType.LCD); 
     text.wrappingWidthProperty().bind(column.widthProperty().subtract(5)); 
     text.textProperty().bind(cell.itemProperty().asString()); 
     return cell; 
    }); 
+0

S'il vous plaît inclure le code qui définit la cellValueFactory de la première colonne. – VGR

+1

Avez-vous une fabrique de cellules personnalisée dans cette colonne? Si oui, postez-le. À côté: réalisez-vous que vous ajoutez continuellement de plus en plus d'auditeurs à la propriété de texte du champ de texte? Finalement, cela mettra l'application à l'arrêt. Il n'est également pas nécessaire de créer une nouvelle liste triée chaque fois que le texte change. –

+0

J'ai ajouté un cellValueFactory. James_D merci de l'avoir signalé ... Je suis encore nouveau à ce sujet donc je n'ai pas remarqué. – zotmer

Répondre

1

Si la cellule est vide, son élément sera null et itemProperty().asString() évaluera une chaîne contenant le mot littéral "null" (similaire à la transmission d'une valeur nulle à PrintStream). Vos besoins de liaison pour traiter les cellules vides comme des cas particuliers:

column.setCellFactory(tc-> { 
    TableCell<Word, Integer> cell = new TableCell<>(); 
    Text text = new Text(); 
    cell.setGraphic(text); 
    text.setTextAlignment(TextAlignment.CENTER); 
    text.setStyle("-fx-fill: -fx-text-background-color;"); 
    text.setFontSmoothingType(FontSmoothingType.LCD); 
    text.wrappingWidthProperty().bind(column.widthProperty().subtract(5)); 
    text.textProperty().bind(Bindings.createStringBinding(() -> { 
     if (cell.isEmpty()) { 
      return null ; 
     } else { 
      return cell.getItem().toString(); 
     } 
    }, cell.emptyProperty(), cell.itemProperty())); 
    return cell; 
}); 

ou si vous devez remplacer updateItem():

column.setCellFactory(tc-> { 
    TableCell<Word, Integer> cell = new TableCell<>() { 
     private Text text = new Text(); 
     { 
      this.setGraphic(text); 
      text.setTextAlignment(TextAlignment.CENTER); 
      text.setStyle("-fx-fill: -fx-text-background-color;"); 
      text.setFontSmoothingType(FontSmoothingType.LCD); 
      text.wrappingWidthProperty().bind(column.widthProperty().subtract(5)); 
     } 

     @Override 
     protected void updateItem(Integer item, boolean empty) { 
      super.updateItem(item, empty); 
      if (empty) { 
       text.setText(null); 
      } else { 
       text.setText(item.toString()); 
      } 
     } 
    }; 
    return cell; 
}); 
+0

Merci beaucoup, j'ai utilisé la deuxième approche comme le premier m'a donné une erreur à 'createStringBinding (()'. Puis-je demander une chose: Si une cellule vide avec un élément entier évalué à "null" String, pourquoi – zotmer

+0

Correction de l'erreur dans la version de liaison Je ne peux pas vraiment commenter le comportement du code que je ne peux pas voir Avez-vous utilisé 'asString()' dans les liaisons de la cellule pour les colonnes de chaînes aussi (ce serait étrange, car elles sont déjà des chaînes) –

+0

Le code pour Strings est presque identique sauf que lors de la liaison j'ai 'text.textProperty(). bind (cell.itemProperty());' – zotmer