title: Drag Nodes of TreeView
body: <p>Using this <a href="https://community.oracle.com/thread/2527130?tstart=0" rel="nofollow">example</a> I want to create TreeView with Nodes that I can drag in order to change their position.</p>
  
  <pre><code>import java.util.ArrayList;
  import java.util.List;
  import java.util.Random;
  import javafx.application.Application;
  import javafx.event.EventHandler;
  import javafx.scene.Scene;
  import javafx.scene.control.TreeCell;
  import javafx.scene.control.TreeItem;
  import javafx.scene.control.TreeItem.TreeModificationEvent;
  import javafx.scene.control.TreeView;
  import javafx.scene.input.ClipboardContent;
  import javafx.scene.input.DataFormat;
  import javafx.scene.input.DragEvent;
  import javafx.scene.input.Dragboard;
  import javafx.scene.input.MouseEvent;
  import javafx.scene.input.TransferMode;
  import javafx.scene.layout.VBox;
  import javafx.stage.Stage;
  import javafx.util.Callback;
  
  public class MainApp extends Application {
  
      private EventHandler&lt;TreeModificationEvent&lt;DynamicTreeNodeModel&gt;&gt; branchExpandedEventHandler;
  
      /**
       * @param args the command line arguments
       */
      public static void main(String[] args) {
          Application.launch(MainApp.class, args);
      }
  
      @Override
      public void start(Stage primaryStage) {
          primaryStage.setTitle("Example Dynamic Tree");
          primaryStage.setResizable(true);
          final VBox box = new VBox();
          box.setFillWidth(false);
          Scene scene = new Scene(box);
          primaryStage.setScene(scene);
          box.getChildren().add(this.getExampleTree());
          primaryStage.show();
      }
  
      private TreeView&lt;DynamicTreeNodeModel&gt; getExampleTree() {
          DynamicTreeNodeModel rootNode = new RandomDynamicTreeNodeModel(null, "Root Node");
  
          TreeView&lt;DynamicTreeNodeModel&gt; treeView = new TreeView&lt;DynamicTreeNodeModel&gt;();
  
          treeView.setCellFactory(new Callback&lt;TreeView&lt;DynamicTreeNodeModel&gt;, TreeCell&lt;DynamicTreeNodeModel&gt;&gt;() {
              @Override
              public TreeCell call(TreeView&lt;DynamicTreeNodeModel&gt; param) {
                  return new DnDCell(param);
              }
          });
  
  
          treeView.setPrefSize(1000, 750);
          TreeItem rootItem = new TreeItem(rootNode);
          branchExpandedEventHandler = new EventHandler&lt;TreeModificationEvent&lt;DynamicTreeNodeModel&gt;&gt;() {
              public void handle(TreeModificationEvent&lt;DynamicTreeNodeModel&gt; event) {
  //                System.out.println("handling event " + event);
                  TreeItem&lt;DynamicTreeNodeModel&gt; item = event.getTreeItem();
                  populateTreeItem(item);
              }
          };
  
          rootItem.addEventHandler(TreeItem.branchExpandedEvent(), branchExpandedEventHandler);
          treeView.setShowRoot(true);
          treeView.setRoot(rootItem);
          populateTreeItem(rootItem);
          rootItem.setExpanded(true);
  //        treeView.setCellFactory(new LearningTreeCellFactory());
          return treeView;
      }
  
      private void populateTreeItem(TreeItem&lt;DynamicTreeNodeModel&gt; item) {
          DynamicTreeNodeModel node = item.getValue();
          boolean isPopulated = node.isPopulated();
          boolean areGrandChildrenPopulated = node.areChildenPopulated();
          node.populateToDepth(2);
          if (!isPopulated) {
              for (DynamicTreeNodeModel childNode : node.getChildren()) {
                  TreeItem childItem = new TreeItem(childNode);
                  childItem.addEventHandler(TreeItem.branchExpandedEvent(), branchExpandedEventHandler);
                  item.getChildren().add(childItem);
              }
          }
          if (!areGrandChildrenPopulated) {
              int i = 0;
              for (TreeItem childItem : item.getChildren()) {
                  // get cooresponding node in the model
                  DynamicTreeNodeModel childNode = node.getChildren().get(i);
                  i++;
                  for (DynamicTreeNodeModel grandChildNode : childNode.getChildren()) {
                      TreeItem grandChildItem = new TreeItem(grandChildNode);
                      grandChildItem.addEventHandler(TreeItem.branchExpandedEvent(), branchExpandedEventHandler);
                      childItem.getChildren().add(grandChildItem);
                  }
              }
          }
      }
  
      private static interface DynamicTreeNodeModel {
  
          public String getName();
  
          public void setName(String name);
  
          public boolean isPopulated();
  
          public boolean areChildenPopulated();
  
          public List&lt;DynamicTreeNodeModel&gt; getChildren();
  
          public void setChildren(List&lt;DynamicTreeNodeModel&gt; children);
  
          public DynamicTreeNodeModel getParent();
  
          public void setParent(DynamicTreeNodeModel parent);
  
          public void populateToDepth(int depth);
  
          @Override
          public String toString();
      }
  
      private static class RandomDynamicTreeNodeModel implements DynamicTreeNodeModel {
  
          private DynamicTreeNodeModel parent;
          private String name;
          private List&lt;DynamicTreeNodeModel&gt; children = null;
  
          public RandomDynamicTreeNodeModel(DynamicTreeNodeModel parent, String name) {
              this.parent = parent;
              this.name = name;
          }
  
          @Override
          public String getName() {
              return name;
          }
  
          @Override
          public void setName(String name) {
              this.name = name;
          }
  
          @Override
          public boolean isPopulated() {
              if (children == null) {
                  return false;
              }
              return true;
          }
  
          @Override
          public boolean areChildenPopulated() {
              if (!this.isPopulated()) {
                  return false;
              }
              for (DynamicTreeNodeModel child : this.children) {
                  if (!child.isPopulated()) {
                      return false;
                  }
              }
              return true;
          }
  
          @Override
          public List&lt;DynamicTreeNodeModel&gt; getChildren() {
              return children;
          }
  
          @Override
          public void setChildren(List&lt;DynamicTreeNodeModel&gt; children) {
              this.children = children;
          }
  
          @Override
          public DynamicTreeNodeModel getParent() {
              return parent;
          }
  
          @Override
          public void setParent(DynamicTreeNodeModel parent) {
              this.parent = parent;
          }
          private static Random random = new Random();
  
          @Override
          public void populateToDepth(int depth) {
              if (depth &lt;= 0) {
                  return;
              }
              if (children == null) {
                  int num = random.nextInt(5);
                  System.out.println("got a random number " + num);
                  children = new ArrayList(num);
                  for (int i = 0; i &lt; num; i++) {
                      children.add(new RandomDynamicTreeNodeModel(this, "child " + i));
                  }
              }
              int childDepth = depth - 1;
              for (DynamicTreeNodeModel child : children) {
                  child.populateToDepth(childDepth);
              }
          }
  
          @Override
          public String toString() {
              return this.name;
          }
      }
  
  
      public class DnDCell extends TreeCell&lt;DynamicTreeNodeModel&gt; {
  
          private TreeView&lt;DynamicTreeNodeModel&gt; parentTree;
  
          public DnDCell(final TreeView&lt;DynamicTreeNodeModel&gt; parentTree) {
              this.parentTree = parentTree;
              // ON SOURCE NODE.
              setOnDragDetected(new EventHandler&lt;MouseEvent&gt;() {
                  @Override
                  public void handle(MouseEvent event) {
                      System.out.println("Drag detected on " + item);
                      if (item == null) {
                          return;
                      }
                      Dragboard dragBoard = startDragAndDrop(TransferMode.MOVE);
                      ClipboardContent content = new ClipboardContent();
                      content.put(DataFormat.PLAIN_TEXT, item.toString());
                      dragBoard.setContent(content);
                      event.consume();
                  }
              });
              setOnDragDone(new EventHandler&lt;DragEvent&gt;() {
                  @Override
                  public void handle(DragEvent dragEvent) {
                      System.out.println("Drag done on " + item);
                      dragEvent.consume();
                  }
              });
              // ON TARGET NODE.
  //            setOnDragEntered(new EventHandler&lt;DragEvent&gt;() {
  //                @Override
  //                public void handle(DragEvent dragEvent) {
  //                    System.out.println("Drag entered on " + item);
  //                    dragEvent.consume();
  //                }
  //            });
              setOnDragOver(new EventHandler&lt;DragEvent&gt;() {
                  @Override
                  public void handle(DragEvent dragEvent) {
                      System.out.println("Drag over on " + item);
                      if (dragEvent.getDragboard().hasString()) {
                          int valueToMove = Integer.parseInt(dragEvent.getDragboard().getString());
                          if (valueToMove != item) {
                              // We accept the transfer!!!!!
                              dragEvent.acceptTransferModes(TransferMode.MOVE);
                          }
                      }
                      dragEvent.consume();
                  }
              });
  //            setOnDragExited(new EventHandler&lt;DragEvent&gt;() {
  //                @Override
  //                public void handle(DragEvent dragEvent) {
  //                    System.out.println("Drag exited on " + item);
  //                    dragEvent.consume();
  //                }
  //            });
              setOnDragDropped(new EventHandler&lt;DragEvent&gt;() {
                  @Override
                  public void handle(DragEvent dragEvent) {
                      System.out.println("Drag dropped on " + item);
                      int valueToMove = Integer.parseInt(dragEvent.getDragboard().getString());
                      TreeItem&lt;DynamicTreeNodeModel&gt; itemToMove = search(parentTree.getRoot(), valueToMove);
                      TreeItem&lt;DynamicTreeNodeModel&gt; newParent = search(parentTree.getRoot(), item);
                      // Remove from former parent.
                      itemToMove.getParent().getChildren().remove(itemToMove);
                      // Add to new parent.
                      newParent.getChildren().add(itemToMove);
                      newParent.setExpanded(true);
                      dragEvent.consume();
                  }
              });
          }
  
          private TreeItem&lt;DynamicTreeNodeModel&gt; search(final TreeItem&lt;DynamicTreeNodeModel&gt; currentNode, final int valueToSearch) {
              TreeItem&lt;DynamicTreeNodeModel&gt; result = null;
              if (currentNode.getValue() == valueToSearch) {
                  result = currentNode;
              } else if (!currentNode.isLeaf()) {
                  for (TreeItem&lt;DynamicTreeNodeModel&gt; child : currentNode.getChildren()) {
                      result = search(child, valueToSearch);
                      if (result != null) {
                          break;
                      }
                  }
              }
              return result;
          }
          private DynamicTreeNodeModel item;
  
          @Override
          protected void updateItem(DynamicTreeNodeModel item, boolean empty) {
              super.updateItem(item, empty);
              this.item = item;
              String text = (item == null) ? null : item.toString();
              setText(text);
          }
      }
  }
  </code></pre>
  
  <p>I tried to implement the example but I'm facing a problem here:</p>
  
  <pre><code>@Controller
  public class FileUploadController {
  
      if (valueToMove != item) {
          // We accept the transfer!!!!!
          dragEvent.acceptTransferModes(TransferMode.MOVE);
      }
      ...............
      if (currentNode.getValue() == valueToSearch) {
  </code></pre>
  
  <p>I'm getting <code>incomparable types: DynamicTreeNodeModel and int</code></p>
  
  <p>Can you help me to fix this issue?</p>