title: In JavaFX, how do I have different context menus for different TreeItem types?
body: <p>I'm trying to assign different context menus based on a parameter in the TreeItem class that I attach to the TreeItem. But I'm not having any success and I can't seem to find any info for how to do this. I've seen examples where a different context menu is used on the treeRoot then a different menu on the first branch but I can't find anything that would indicate how to have different context menus for the first then second branch in a TreeView.</p>
  <p>I created these working classes to demonstrate where I'm at with this now, but it doesn't work as it never seems to actually pass the leaf nodes into the CellNode based on the output Im getting and the fact that the same menu is being applied to both levels of TreeItems.</p>
  <p>Here is the GUI class:</p>
  <pre><code>public class MainUI {
  
      public MainUI() {
          makeControls();
          ap =  new AnchorPane(treeView);
          Stage stage = new Stage();
          Scene scene = new Scene(ap);
          stage.setScene(scene);
          stage.show();
          stage.getScene().getWindow().centerOnScreen();
          stage.getScene().getWindow().sizeToScene();
      }
  
      private final AnchorPane         ap;
      private       TreeView           treeView;
      private       TreeItem&lt;TypeNode&gt; treeRoot;
  
  
      private void makeControls() {
          treeView = new TreeView&lt;&gt;();
          treeRoot = new TreeItem&lt;&gt;(new TypeNode());
          treeView.setRoot(treeRoot);
          treeView.setShowRoot(false);
          treeView.setCellFactory(new CellFactory());
          fillTree();
  
      }
  
      private void fillTree() {
          new Thread(() -&gt; {
              for (int x=1; x &lt;= 10; x++) {
                  TreeItem&lt;TypeNode&gt; branch = new TreeItem&lt;&gt;(new TypeNode(Type.TYPE_A));
                  for(int y=1; y &lt;= 5; y++) {
                      TreeItem&lt;TypeNode&gt; leaf = new TreeItem&lt;&gt;(new TypeNode(Type.TYPE_B));
                      branch.getChildren().add(leaf);
                  }
                  treeRoot.getChildren().add(branch);
              }
          }).start();
      }
  }
  </code></pre>
  <p>The CellFactory:</p>
  <pre><code>public class CellFactory implements Callback&lt;TreeView&lt;TypeNode&gt;, TreeCell&lt;TypeNode&gt;&gt; {
      @Override public TreeCell&lt;TypeNode&gt; call(TreeView&lt;TypeNode&gt; treeView) {
          TreeCell&lt;TypeNode&gt; cell = new CellNode&lt;&gt;() {
              @Override
              public void updateItem(final TypeNode item, final boolean empty) {
                  super.updateItem(item, empty);
                  if (item == null) return;
                  setText(getTreeItem().getValue().getText());
                  setGraphic(getTreeItem().getGraphic());
              }
          };
          return cell;
      }
  }
  </code></pre>
  <p>The CellNode:</p>
  <pre><code>public class CellNode&lt;T&gt; extends TreeCell&lt;TypeNode&gt; {
  
      private final ContextMenu menuA = new ContextMenu();
      private final ContextMenu menuB = new ContextMenu();
  
      public CellNode() {
          MenuItem menuA1  = new MenuItem(&quot;New A Item&quot;);
          MenuItem menuA2 = new MenuItem(&quot;Copy A Item&quot;);
          MenuItem menuB1  = new MenuItem(&quot;New B Item&quot;);
          MenuItem menuB2 = new MenuItem(&quot;Copy B Item&quot;);
          menuA.getItems().setAll(menuA1,menuA2);
          menuB.getItems().setAll(menuB1,menuB2);
          menuA1.setOnAction(e -&gt; System.out.println(&quot;menuA1&quot;));
          menuA2.setOnAction(e -&gt; System.out.println(&quot;menuA2&quot;));
          menuB1.setOnAction(e -&gt; System.out.println(&quot;menuB1&quot;));
          menuB2.setOnAction(e -&gt; System.out.println(&quot;menuB2&quot;));
      }
  
      @Override
      public void updateItem(TypeNode item, boolean empty) {
          super.updateItem(item, empty);
          if (empty) {
              setText(null);
              setGraphic(null);
          } else {
              if (!isEditing()) {
                  System.out.println(getTreeItem().getValue().getType());
                  if (!getTreeItem().isLeaf() &amp;&amp; getTreeItem().getParent() != null) {
                      if(getTreeItem().getValue().getType().equals(Type.TYPE_A)) {
                          setContextMenu(menuA);
                      }
                      if(getTreeItem().getValue().getType().equals(Type.TYPE_B)) {
                          setContextMenu(menuB);
                      }
                  }
              }
          }
      }
  
      private String getString() {
          return getItem() == null ? &quot;&quot; : getItem().toString();
      }
  }
  </code></pre>
  <p>TypeNode:</p>
  <pre><code>public class TypeNode {
  
      private       String text = &quot;&quot;;
      private final Type   type;
  
      private static int var = 0;
  
      public TypeNode() {
          this.type = Type.NO_TYPE;
      }
  
      public TypeNode(Type type) {
          this.type = type;
          var++;
          this.text = this.type.toString() + &quot;: &quot; + var;
      }
  
      public String getText() {
          return text;
      }
  
      public Type getType() {
          return type;
      }
  
      @Override public String toString() {
          return text;
      }
  }
  </code></pre>
  <p>And Type enum:</p>
  <pre><code>public enum Type {
      TYPE_A,
      TYPE_B,
      NO_TYPE
  }
  </code></pre>
  <p>Here is the output from the loading of the Scene:</p>
  <pre><code>TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  TYPE_A
  </code></pre>
  <p>And here you can see that menuB never gets assigned to anything:</p>
  <p><a href="https://i.stack.imgur.com/8xjFs.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8xjFs.png" alt="enter image description here" /></a></p>
  <p><a href="https://i.stack.imgur.com/QFjEG.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/QFjEG.png" alt="enter image description here" /></a></p>
  <p>CLEARLY, I'm doing something wrong, but I can't figure it out... any assistance or advice would be much appreciated.</p>
  <p>Mike</p>