2013-06-03 38 views
3

我已經使用JAVA FX 2站點上的示例樹用戶界面,並將類型從字符串更改爲PayString,似乎都工作正常。我的下一步是在setCellFactory'TextFieldTreeCellImpl'中,我需要爲單元格分配不同的上下文菜單,具體取決於PayString.level整數的值。參考TreeView類型字符串以外的數據字段

如何引用與當前單元格關聯的數據字段的值。

下面是包中的兩個源代碼文件treeviewsample。爲了便於查找,我需要這些數據的位置標有+++++++++++++++++++++++++。

`/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package treeviewsample; 

import java.util.Arrays; 
import java.util.List; 
import javafx.application.Application; 
import javafx.beans.property.IntegerProperty; 
import javafx.event.Event; 
import javafx.event.EventHandler; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.control.TreeCell; 
import javafx.scene.control.TreeItem; 
import javafx.scene.control.TreeView; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.input.KeyCode; 
import javafx.scene.input.KeyEvent; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

import javafx.beans.property.SimpleStringProperty; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.MenuItem; 
import javafx.scene.layout.VBox; 

public class TreeViewSample extends Application { 

    private final Node rootIcon; 
    private final Image depIcon; 
    List<Employee> employees = Arrays.<Employee>asList(
      new Employee(1, "Ethan Williams", "Sales Department"), 
      new Employee(2, "Emma Jones", "Sales Department"), 
      new Employee(3, "Michael Brown", "Sales Department"), 
      new Employee(4, "Anna Black", "Sales Department"), 
      new Employee(5, "Rodger York", "Sales Department"), 
      new Employee(6, "Susan Collins", "Sales Department"), 
      new Employee(7, "Mike Graham", "IT Support"), 
      new Employee(8, "Judy Mayer", "IT Support"), 
      new Employee(9, "Gregory Smith", "IT Support"), 
      new Employee(10, "Jacob Smith", "Accounts Department"), 
      new Employee(11, "Isabella Johnson", "Accounts Department")); 
    TreeItem<PayString> rootNode; 
    Integer next; 

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

    public TreeViewSample() { 
     this.next = 12; 
     this.depIcon = new Image(getClass().getResourceAsStream("department.png")); 
     this.rootIcon = new ImageView(new Image(getClass().getResourceAsStream("root.png"))); 
     this.rootNode = new TreeItem<>(new PayString ("MyCompany Human Resources", 0,0), rootIcon); 
    } 

    @Override 
    public void start(Stage stage) { 
     rootNode.setExpanded(true); 
     for (Employee employee : employees) { 
      TreeItem<PayString> empLeaf = new TreeItem<>(new PayString(employee.getName(),2,employee.getId())); 
      boolean found = false; 
      for (TreeItem<PayString> depNode : rootNode.getChildren()) { 
       if (depNode.getValue().toString().contentEquals(employee.getDepartment())){ 
        depNode.getChildren().add(empLeaf); 
        found = true; 
        break; 
       } 
      } 
      if (!found) { 
       TreeItem depNode = new TreeItem<>(new PayString(employee.getDepartment(),1,employee.getId()), 
        new ImageView(depIcon) 
       ); 
       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<PayString> treeView = new TreeView<>(rootNode); 
     treeView.setEditable(true); 
     treeView.setCellFactory(new Callback<TreeView<PayString>,TreeCell<PayString>>(){ 
      @Override 
      public TreeCell<PayString> call(TreeView<PayString> p) { 
       return new TextFieldTreeCellImpl(); 
      } 
     }); 

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

    private final class TextFieldTreeCellImpl extends TreeCell<PayString> { 

     private TextField textField; 
     private ContextMenu addMenu = new ContextMenu(); 

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
* This is where I need to be able to extract the values in the current TreeCell<PayString> 
* to be able to create the appropriate context menu. 
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
*/ 

     private String curr = getString(); 

     public TextFieldTreeCellImpl() { 
      TreeItem<PayString> paystring = treeItemProperty().getValue(); 
      MenuItem addMenuItem = new MenuItem("Add Employee"); 
      MenuItem addMenuItem2 = new MenuItem("Add Address"); 
      MenuItem addMenuItem3 = new MenuItem(curr); 
      addMenu.getItems().add(addMenuItem2); 
      addMenu.getItems().add(addMenuItem3); 
      addMenuItem.setOnAction(new EventHandler() { 
       @Override 
       public void handle(Event t) { 
        TreeItem newEmployee = 
         new TreeItem<>(new PayString ("New Employee",3,next)); 
          next ++; 
          getTreeItem().getChildren().add(newEmployee); 
       } 
      }); 
     } 

     @Override 
     public void startEdit() { 
      super.startEdit(); 

      if (textField == null) { 
       createTextField(); 
      } 
      setText(null); 
      setGraphic(textField); 
      textField.selectAll(); 
     } 

     @Override 
     public void cancelEdit() { 
      super.cancelEdit(); 

      setText(getString()); 
      setGraphic(getTreeItem().getGraphic()); 
     } 

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

      if (empty) { 
       setText(null); 
       setGraphic(null); 
      } else { 
       if (isEditing()) { 
        if (textField != null) { 
         textField.setText(getString()); 
        } 
        setText(null); 
        setGraphic(textField); 
       } else { 
        setText(getString()); 
        setGraphic(getTreeItem().getGraphic()); 
        if (
         !getTreeItem().isLeaf()&&getTreeItem().getParent()!= null 
        ){ 
          setContextMenu(addMenu); 
       } 
       } 
      } 
     } 

     private void createTextField() { 
      textField = new TextField(getString()); 
      textField.setOnKeyReleased(new EventHandler<KeyEvent>() { 

       @Override 
       public void handle(KeyEvent t) { 
        if (t.getCode() == KeyCode.ENTER) { 
         commitEdit(new PayString (textField.getText(),3,next)); 
        } else if (t.getCode() == KeyCode.ESCAPE) { 
         cancelEdit(); 
        } 
       } 
      }); 

     } 

     private String getString() { 
      return getItem() == null ? "" : getItem().toString(); 
     } 
    } 

    public static class Employee { 

     private final SimpleStringProperty name; 
     private final SimpleStringProperty department; 
     private final Integer id; 

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

     public Integer getId() { 
      return id; 
     } 

     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); 
     } 
    } 
} 

    package treeviewsample; 

    import java.util.Objects; 
    import javafx.beans.property.IntegerProperty; 
    import javafx.beans.property.SimpleIntegerProperty; 
    import javafx.beans.property.SimpleStringProperty; 
    import javafx.beans.property.StringProperty; 

    /** 
    * 
    * @author Len 
    */ 
    public class PayString { 
     private final String description; 
     private final Integer level; 
     private final Integer id; 

     public PayString(String description, Integer level, Integer id) { 
      this.id = id; 
      this.level = level; 
      this.description = description; 
     } 

     public int getId() { 
      return id; 
     } 



     public int getLevel() { 
      return level; 
     } 


     public String getDescription() { 
      return description; 
     } 


     @Override 
     public int hashCode() { 
      int hash = 7; 
      return hash; 
     } 

      public boolean contentEquals(Object obj) { 
      if (obj == null) { 
       return false; 
      } 
      if (getClass() != obj.getClass()) { 
       return false; 
      } 
      final PayString other = (PayString) obj; 
      if (!Objects.equals(this.description, other.description)) { 
       return false; 
      } 
      return true; 
     } 

     @Override 
     public String toString() { 
      return description; 
     } 


    } 
` 

回答

0

你總是可以通過調用

PayString value = getTreeItem().getValue() 

訪問與你的相關的當前數據。但是沒有1:小區和值之間一對一的關係。 JavaFX創建它需要顯示的許多TreeCells。然後,它通過動態調用方法

public void updateItem(PayString item, boolean empty) { ... } 

在這裏,您可以設置取決於當前的數據項的上下文菜單將它們分配到底層數據項。在那裏你可以獲得作爲參數傳入的數據項。

在您標記爲當前數據項的代碼位置將爲null