2014-02-22 41 views
2

我想爲JavaFX創建上下文菜單。這是我測試的代碼。但由於某種原因,當我右鍵單擊樹節點時沒有上下文菜單。你能幫我找到我的錯誤嗎?JavaFX樹的上下文菜單

import java.util.Arrays; 
import java.util.List; 
import javafx.application.Application; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.ContextMenuBuilder; 
import javafx.scene.control.MenuItemBuilder; 
import javafx.scene.control.TreeCell; 
import javafx.scene.control.TreeItem; 
import javafx.scene.control.TreeView; 
import javafx.scene.control.cell.TextFieldTreeCell; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class MainApp extends Application 
{ 
    List<Employee> employees = Arrays.<Employee>asList(
     new Employee("New Chassi", "New Datacenter"), 
     new Employee("New Battery", "New Rack"), 
     new Employee("New Chassi", "New Server"), 
     new Employee("Anna Black", "Sales Department"), 
     new Employee("Rodger York", "Sales Department"), 
     new Employee("Susan Collins", "Sales Department"), 
     new Employee("Mike Graham", "IT Support"), 
     new Employee("Judy Mayer", "IT Support"), 
     new Employee("Gregory Smith", "IT Support"), 
     new Employee("Jacob Smith", "Accounts Department"), 
     new Employee("Isabella Johnson", "Accounts Department")); 
    TreeItem<String> rootNode = new TreeItem<>("MyCompany Human Resources"); 

    public static void main(String[] args) 
    { 
     Application.launch(args); 
    } 

    TreeView<String> treeView = new TreeView<>(rootNode); 

    @Override 
    public void start(Stage stage) 
    { 

     rootNode.setExpanded(true); 
     for (Employee employee : employees) 
     { 
      TreeItem<String> empLeaf = new TreeItem<>(employee.getName()); 
      boolean found = false; 
      for (TreeItem<String> depNode : rootNode.getChildren()) 
      { 
       if (depNode.getValue().contentEquals(employee.getDepartment())) 
       { 
        depNode.getChildren().add(empLeaf); 
        found = true; 
        break; 
       } 
      } 
      if (!found) 
      { 
       TreeItem<String> depNode = new TreeItem<>(
        employee.getDepartment()//,new ImageView(depIcon) // Set picture 
       ); 
       rootNode.getChildren().add(depNode); 
       depNode.getChildren().add(empLeaf); 
      } 
     } 

     stage.setTitle("Tree View Sample"); 
     VBox box = new VBox(); 
     final Scene scene = new Scene(box, 400, 300); 
     scene.setFill(Color.LIGHTGRAY); 

     treeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() 
     { 

      @Override 
      public TreeCell<String> call(TreeView<String> arg0) 
      { 
       // custom tree cell that defines a context menu for the root tree item 
       return new MyTreeCell(); 
      } 
     }); 

     box.getChildren().add(treeView); 
     stage.setScene(scene); 
     stage.show(); 
    } 

    public static class Employee 
    { 

     private final SimpleStringProperty name; 
     private final SimpleStringProperty department; 

     private Employee(String name, String department) 
     { 
      this.name = new SimpleStringProperty(name); 
      this.department = new SimpleStringProperty(department); 
     } 

     public String getName() 
     { 
      return name.get(); 
     } 

     public void setName(String fName) 
     { 
      name.set(fName); 
     } 

     public String getDepartment() 
     { 
      return department.get(); 
     } 

     public void setDepartment(String fName) 
     { 
      department.set(fName); 
     } 
    } 

    class MyTreeCell extends TextFieldTreeCell<String> 
    { 
     private ContextMenu rootContextMenu; 

     public MyTreeCell() 
     { 
      // instantiate the root context menu 
      rootContextMenu 
       = ContextMenuBuilder.create() 
       .items(
        MenuItemBuilder.create() 
        .text("Menu Item") 
        .onAction(
         new EventHandler<ActionEvent>() 
         { 
          @Override 
          public void handle(ActionEvent arg0) 
          { 
           System.out.println("Menu Item Clicked!"); 
          } 
         } 
        ) 
        .build() 
       ) 
       .build(); 
     } 

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

      // if the item is not empty and is a root... 
      if (!empty && getTreeItem().getParent() == null) 
      { 
       setContextMenu(rootContextMenu); 
      } 
     } 
    } 

} 

回答

8

您應該將上下文菜單分配給TreeView,而不是將其分配給單元工廠。這裏是上下文菜單中使用的代碼:

import java.util.Arrays; 
import java.util.List; 
import javafx.application.Application; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.ContextMenuBuilder; 
import javafx.scene.control.MenuItemBuilder; 
import javafx.scene.control.TreeCell; 
import javafx.scene.control.TreeItem; 
import javafx.scene.control.TreeView; 
import javafx.scene.control.cell.TextFieldTreeCell; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class Test extends Application 
{ 
    List<Employee> employees = Arrays.<Employee>asList(
     new Employee("New Chassi", "New Datacenter"), 
     new Employee("New Battery", "New Rack"), 
     new Employee("New Chassi", "New Server"), 
     new Employee("Anna Black", "Sales Department"), 
     new Employee("Rodger York", "Sales Department"), 
     new Employee("Susan Collins", "Sales Department"), 
     new Employee("Mike Graham", "IT Support"), 
     new Employee("Judy Mayer", "IT Support"), 
     new Employee("Gregory Smith", "IT Support"), 
     new Employee("Jacob Smith", "Accounts Department"), 
     new Employee("Isabella Johnson", "Accounts Department")); 
    TreeItem<String> rootNode = new TreeItem<>("MyCompany Human Resources"); 

    public static void main(String[] args) 
    { 
     Application.launch(args); 
    } 

    TreeView<String> treeView = new TreeView<>(rootNode); 

    @Override 
    public void start(Stage stage) 
    { 

     // instantiate the root context menu 
     ContextMenu rootContextMenu 
      = ContextMenuBuilder.create() 
      .items(
       MenuItemBuilder.create() 
       .text("Menu Item") 
       .onAction(
        new EventHandler<ActionEvent>() 
        { 
         @Override 
         public void handle(ActionEvent arg0) 
         { 
          System.out.println("Menu Item Clicked!"); 
         } 
        } 
       ) 
       .build() 
      ) 
      .build(); 

     treeView.setContextMenu(rootContextMenu); 

     rootNode.setExpanded(true); 
     for (Employee employee : employees) 
     { 
      TreeItem<String> empLeaf = new TreeItem<>(employee.getName()); 
      boolean found = false; 
      for (TreeItem<String> depNode : rootNode.getChildren()) 
      { 
       if (depNode.getValue().contentEquals(employee.getDepartment())) 
       { 
        depNode.getChildren().add(empLeaf); 
        found = true; 
        break; 
       } 
      } 
      if (!found) 
      { 
       TreeItem<String> depNode = new TreeItem<>(
        employee.getDepartment()//,new ImageView(depIcon) // Set picture 
       ); 
       rootNode.getChildren().add(depNode); 
       depNode.getChildren().add(empLeaf); 
      } 
     } 

     stage.setTitle("Tree View Sample"); 
     VBox box = new VBox(); 
     final Scene scene = new Scene(box, 400, 300); 
     scene.setFill(Color.LIGHTGRAY); 


     box.getChildren().add(treeView); 
     stage.setScene(scene); 
     stage.show(); 
    } 

    public static class Employee 
    { 

     private final SimpleStringProperty name; 
     private final SimpleStringProperty department; 

     private Employee(String name, String department) 
     { 
      this.name = new SimpleStringProperty(name); 
      this.department = new SimpleStringProperty(department); 
     } 

     public String getName() 
     { 
      return name.get(); 
     } 

     public void setName(String fName) 
     { 
      name.set(fName); 
     } 

     public String getDepartment() 
     { 
      return department.get(); 
     } 

     public void setDepartment(String fName) 
     { 
      department.set(fName); 
     } 
    } 


} 
1

ContextMenuBuilderMenuItemBuilder(這是在公認的答案使用)被棄用的JavaFX 8,將在以後的版本中刪除。

在與兩個項目,一個具有圖標和一個沒有圖標的JavaFX的8例如:

MenuItem entry1 = new MenuItem("Test with Icon", graphicNode); 
entry1.setOnAction(ae -> ...); 
MenuItem entry2 = new MenuItem("Test without Icon"); 
entry2.setOnAction(ae -> ...); 

myTreeView.setContextMenu(new ContextMenu(entry1, entry2));