title: JavaFX, bind object field to TreeItem for automatic update of TreeItem
body: <p>Is there a way to bind an object's field to a TreeItem so that when the field is changed, the TreeItem is automatically updated in the TreeView? 
  I have objects with several fields that are set in TreeItems in a TreeView. The objects fields are updated sometimes at 5 to 10 times per second via their setters and I would like the TreeItems to update on the fly as the fields change. Any help on this would be greatly appreciated. I can't seem to find a way to do this other than reloading the entire TreeView.</p>
  
  <p>Edit: Here is the existing code...
  The list listener sets up the treeview for the player list. If the number of objects in the list changes, the tree is redrawn. That is all fine. What I want is, if you were to place code in the handle button click method that continuously changes player attributes(in a loop, maybe 2-10 times per second), that should be reflected in the treeview as those attributes change.(Just a simulation, I cant get into how those attributes are really being changed at that rate). An example of how to do this would be great.</p>
  
  <pre><code>package application;
  
  import java.io.IOException;
  import javafx.application.Application;
  import javafx.fxml.FXML;
  import javafx.fxml.FXMLLoader;
  import javafx.stage.Stage;
  import viewcontroller.PlayerViewController;
  import javafx.scene.Scene;
  import javafx.scene.layout.AnchorPane;
  
  
  
  
  public class Main extends Application {
      private Stage mainStage;
      @FXML
      private AnchorPane mainView;
  
      @Override
      public void start(Stage mainStage) {
             this.mainStage = mainStage;
             PlayerList.playerListListener();
             this.showMainLayout();       
      }
  
      /**
       * shows the main screen
       */
      public void showMainLayout() {
           FXMLLoader loader = new FXMLLoader();
           loader.setLocation(Main.class.getResource("/viewcontroller/playerView.fxml"));           
           try {
              mainView = (AnchorPane) loader.load();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
           Scene scene = new Scene(mainView);
           mainStage.sizeToScene();
           mainStage.setScene(scene);
           mainStage.show();
           PlayerViewController controller = loader.getController();
           controller.setMainApp(this);
      }
  
      public static void main(String[] args) {
          launch(args);
      }
  }
  
  package model;
  
  import javafx.beans.property.SimpleStringProperty;
  import javafx.beans.property.StringProperty;
  
  public class Player {
      private StringProperty str1 = new SimpleStringProperty();
      private StringProperty str2 = new SimpleStringProperty();
      private StringProperty str3 = new SimpleStringProperty();
  
      public Player() {
  
      }
  
      public Player(String str1, String str2, String str3) {
          super();
          this.str1 = new SimpleStringProperty(str1);
          this.str2 = new SimpleStringProperty(str2);
          this.str3 = new SimpleStringProperty(str3);
      }
      public StringProperty str1() {
          return str1;
      }
      public String getStr1() {
          return str1.get();
      }
      public void setStr1(String str1) {
          this.str1.set(str1);
      }
      public StringProperty str2() {
          return str2;
      }
      public String getStr2() {
          return str2.get();
      }
      public void setStr2(String str2) {
          this.str2.set(str2);
      }
      public StringProperty str3() {
          return str3;
      }
      public String getStr3() {
          return str3.get();
      }
      public void setStr3(String str3) {
          this.str3.set(str3);
      }
  
  
  
  
  }
  
  package application;
  
  import javafx.collections.FXCollections;
  import javafx.collections.ListChangeListener;
  import javafx.collections.ObservableList;
  import javafx.scene.control.TreeItem;
  import model.Player;
  
  public class PlayerList {
  
      private final ObservableList&lt;Player&gt; playerList = FXCollections.observableArrayList();
  
      private static PlayerList instance = new PlayerList();
  
      public static TreeItem&lt;String&gt; rootNode = new TreeItem&lt;String&gt;("Root");
  
      private PlayerList() {}
  
      public ObservableList&lt;Player&gt; getPlayerList() {
          return playerList;
      }
  
      public static PlayerList getInstance() {
          return instance;
      }
  
  
      public static void playerListListener() {
          //adds a list listener which reloads tree if objects are added or removed
          PlayerList.getInstance().getPlayerList().addListener((ListChangeListener&lt;? super Player&gt;) new ListChangeListener&lt;Player&gt;() {
  
              @SuppressWarnings("unchecked")
              public void onChanged(Change&lt;? extends Player&gt; change) {
                  //re-sort list
                  //System.out.println("List changed");
                  rootNode.getChildren().clear();//clear tree before reloading on list change
  
                  for(Player p: PlayerList.getInstance().getPlayerList()) {
                      //Parent Node
                      TreeItem&lt;String&gt; playerName = new TreeItem&lt;String&gt;(p.getStr1());
                      //Items
                      TreeItem&lt;String&gt; attr1 = new TreeItem&lt;String&gt;(p.getStr2());
                      TreeItem&lt;String&gt; attr2 = new TreeItem&lt;String&gt;(p.getStr3());
  
                      playerName.getChildren().addAll(attr1, attr2);
                      playerName.setExpanded(true);
                      rootNode.getChildren().add(playerName);
                      rootNode.setExpanded(true);
                  }
  
              }
          });
      }
  
  }
  
  package viewcontroller;
  
  import java.net.URL;
  import java.util.ResourceBundle;
  
  import application.Main;
  import application.PlayerList;
  import javafx.fxml.FXML;
  import javafx.fxml.Initializable;
  import javafx.scene.control.TreeView;
  import javafx.scene.layout.VBox;
  import model.Player;
  
  public class PlayerViewController implements Initializable {
      @FXML
      private VBox vbox;
      private TreeView&lt;String&gt; treeView;
      public void setMainApp(Main main) {
          // TODO Auto-generated method stub
  
      }
  
      @Override
      public void initialize(URL location, ResourceBundle resources) {
          // TODO Auto-generated method stub
          Player p1 = new Player("Name1", "Attr1", "Attr2");
          Player p2 = new Player("Name2", "Attr1", "Attr2");
          Player p3 = new Player("Name3", "Attr1", "Attr2");
          PlayerList.getInstance().getPlayerList().addAll(p1, p2, p3);//add players to list
  
          treeView = new TreeView&lt;String&gt;(PlayerList.rootNode);
          treeView.setShowRoot(false);
          vbox.getChildren().add(treeView);//add tree view to GUI
  
      }
      @FXML
      private void handleButtonClick() {
          /*this method can hold code that would run in a loop, continuously setting new values
          on p1, p2, and p3 attributes and would show the tree items updating automatically*/
      }
  
  }
  
  &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;?import javafx.scene.control.*?&gt;
  &lt;?import java.lang.*?&gt;
  &lt;?import javafx.scene.layout.*?&gt;
  &lt;?import javafx.scene.layout.AnchorPane?&gt;
  
  &lt;AnchorPane fx:id="mainView" prefHeight="400.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="viewcontroller.PlayerViewController"&gt;
     &lt;children&gt;
        &lt;VBox fx:id="vbox" layoutX="14.0" layoutY="14.0" prefHeight="200.0" prefWidth="100.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"&gt;
           &lt;children&gt;
              &lt;Button mnemonicParsing="false" onAction="#handleButtonClick" text="Button" /&gt;
           &lt;/children&gt;
        &lt;/VBox&gt;
     &lt;/children&gt;
  &lt;/AnchorPane&gt;
  </code></pre>