2013-06-03 39 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