2013-08-10 3 views
0

Débogage pour le code ci-dessous, il montre que la méthode updateItem() est appelée plusieurs fois, mais je suis incapable de comprendre pourquoi il est appelé plusieurs fois.ListView dans javafx, ajoute plusieurs cellules

Je voulais ajouter l'info-bulle à ListView.

// THIS TO ADD TOOLTIP, NOT WORKING FULLY. 
lstComments.setCellFactory(new Callback<ListView<String>, ListCell<String>>() { 
    @Override 
    public ListCell<String> call(ListView<String> p) { 
     final Tooltip tt = new Tooltip(); 
     final ListCell<String> cell = new ListCell<String>() { 
      String message = ca.getMessage(); 

      @Override 
      public void updateItem(String s, boolean empty) { 
       super.updateItem(s, empty); 
       tt.setText(message); 
       setTooltip(tt); 
      } 
     }; 

     cell.setText(ca.getMessage()); 
     return cell; 
    } 
}); 

Répondre

4

Recommandation

Je trouve la facilité d'utilisation des infobulles sur les cellules ListView horribles, parce que les événements de souris standard d'interception infobulles utilisés pour sélectionner les lignes, faites défiler la liste, etc. Je recommande donc de ne pas placer infobulles sur les cellules ListView.

Pourquoi plusieurs cellules sont créées et updateItem est appelé plusieurs fois

Il est prévu que ListView ont plusieurs cellules et que updateItem() est potentiellement appelé plusieurs fois pour chaque cellule.

Une cellule est créée pour chaque ligne de ListView affichée sur la scène, même si certaines cellules sont vides. Quelques autres cellules hors écran sont généralement créées pour une gestion de défilement efficace. Chaque fois que les données sous-jacentes d'un ListView sont initialement définies ou modifiées, ou que la liste est défilée, updateItem() sera invoqué sur les cellules pertinentes pour mettre à jour le contenu de la cellule. Dans le cas de faire défiler une grande liste, updateItem() sera invoqué de nombreuses fois pour chaque cellule.

Exemple de code pour définir une info-bulle sur les cellules ListView

Le code ci-dessous est basé sur le Oracle JavaFX tutorial ListView sample, mais personnalise pour créer infobulles pour les cellules lorsque vous passez la souris sur eux.

mport javafx.application.Application; 
import javafx.collections.*; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.layout.*; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.scene.text.Font; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class ListViewSample extends Application { 

    ListView<String> list = new ListView<String>(); 
    ObservableList<String> data = FXCollections.observableArrayList(
      "chocolate", "salmon", "gold", "coral", "darkorchid", 
      "darkgoldenrod", "lightsalmon", "black", "rosybrown", "blue", 
      "blueviolet", "brown"); 
    final Label label = new Label(); 

    @Override 
    public void start(Stage stage) { 
     VBox box = new VBox(); 
     Scene scene = new Scene(box, 200, 200); 
     stage.setScene(scene); 
     stage.setTitle("ListViewSample"); 
     box.getChildren().addAll(list, label); 
     VBox.setVgrow(list, Priority.ALWAYS); 

     label.setLayoutX(10); 
     label.setLayoutY(115); 
     label.setFont(Font.font("Verdana", 20)); 

     list.setItems(data); 

     list.setCellFactory(new Callback<ListView<String>, ListCell<String>>() { 
      @Override public ListCell<String> call(ListView<String> list) { 
       return new ColorRectCell(); 
      } 
     }); 

     list.getSelectionModel().selectedItemProperty().addListener(
       (ov, old_val, new_val) -> { 
         label.setText(new_val); 
         label.setTextFill(Color.web(new_val)); 
       }); 
     stage.show(); 
    } 

    static class ColorRectCell extends ListCell<String> { 
     final Rectangle swatch = new Rectangle(30, 30); 
     final Tooltip tip = new Tooltip(); 

     public ColorRectCell() { 
      tip.setGraphic(swatch); 
     } 

     @Override 
     public void updateItem(String color, boolean empty) { 
      super.updateItem(color, empty); 

      if (color != null) { 
       swatch.setFill(Color.valueOf(color.toUpperCase())); 
       setText(color); 
       setTooltip(tip); 
      } else { 
       setText(""); 
       setTooltip(null); 
      } 
     } 
    } 

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

Merci d'expliquer les choses. –

Questions connexes