Javafx 2 JavaFX2TreeView模型参考

Javafx 2 JavaFX2TreeView模型参考,javafx-2,javafx,Javafx 2,Javafx,在onMouseClick事件期间,我试图取回TreeItemsvalueProperty。我有以下类型的TreeView: @FXML private TreeView<Pair<URIImpl,String>> myTreeview; 就我所知,本例中的目标对象是不包含封装模型引用的标签文本。谁能给点建议吗?这似乎是一个非常基本的特征。单向绑定…带有某种引用。我不想编辑TreeItems 此线程类似于问题: 谢谢关键是在树视图上定义一个,并在单元工厂中将鼠标单击事

onMouseClick
事件期间,我试图取回
TreeItem
s
valueProperty
。我有以下类型的
TreeView

@FXML
private TreeView<Pair<URIImpl,String>> myTreeview;
就我所知,本例中的目标对象是不包含封装模型引用的
标签
文本。谁能给点建议吗?这似乎是一个非常基本的特征。单向绑定…带有某种引用。我不想编辑
TreeItem
s

此线程类似于问题:

谢谢

关键是在树视图上定义一个,并在单元工厂中将鼠标单击事件处理程序添加到树单元中。这样定义的鼠标单击事件处理程序将具有对支持树单元的模型对象的完全访问权限,并且可以使用它做任何事情

在下面的示例中,当用户单击树中的单元格时,单击处理程序从与单击的单元格相关的基础模型项中提取信息,并将该信息呈现到树下的标签中

TreeApplication.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.stage.*;

public class TreeApplication extends Application {
  @Override public void start(final Stage stage) throws Exception {
    final FXMLLoader loader = new FXMLLoader(
      getClass().getResource("treeInterface.fxml")
    );
    final Parent root = (Parent) loader.load();

    stage.setScene(new Scene(root));
    stage.show();
  }

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

import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.util.Callback;
import javafx.util.Pair;

import java.net.URL;
import java.util.ResourceBundle;

public class TreeController implements Initializable {
  @FXML private TreeView<Pair<URIImpl,String>> treeView;
  @FXML private Label clickedPair;

  @Override public void initialize(URL location, ResourceBundle resources) {
    treeView.setCellFactory(new Callback<TreeView<Pair<URIImpl, String>>, TreeCell<Pair<URIImpl, String>>>() {
      @Override public TreeCell<Pair<URIImpl, String>> call(TreeView<Pair<URIImpl, String>> treeView) {
        return new TreeCell<Pair<URIImpl, String>>() {
          final ImageView iconView = new ImageView();
          @Override protected void updateItem(final Pair<URIImpl, String> pair, boolean empty) {
            super.updateItem(pair, empty);

            if (!empty && pair != null) {
              setText(
                pair.getValue()
              );
              setGraphic(
                iconView
              );
              iconView.setImage(pair.getKey().getImage());
            } else {
              setText(null);
              setGraphic(null);
            }

            setOnMouseClicked(new EventHandler<MouseEvent>() {
              @Override
              public void handle(MouseEvent event) {
                clickedPair.setText(
                  "Key: " + pair.getKey() + " Value: " + pair.getValue()
                );
              }
            });
          }
        };
      }
    });

    loadTreeItems(
      createPair("http://www.google.com",    "google.com",    "Google"),
      createPair("http://www.microsoft.com", "microsoft.com", "Microsoft"),
      createPair("http://www.yahoo.com",     "yahoo.com",     "Yahoo")
    );
  }  

  private Pair<URIImpl, String> createPair(String uri, String domain, String name) {
    return new Pair<>(new URIImpl(uri, domain), name);
  }

  private void loadTreeItems(Pair<URIImpl,String>... rootItems) {
    TreeItem<Pair<URIImpl,String>> root = new TreeItem(createPair("N/A", "", "Root Node"));
    root.setExpanded(true);

    for (Pair<URIImpl, String> pair: rootItems) {
      root.getChildren().add(
        new TreeItem<>(
          pair
        )
      );
    }

    treeView.setRoot(root);
  }

}
treeInterface.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns:fx="http://javafx.com/fxml" fx:controller="tests.treesample.TreeController">
    <TreeView fx:id="treeView" layoutX="0" layoutY="0" prefHeight="193.0" prefWidth="471.0" />
    <Label    fx:id="clickedPair" layoutX="0" layoutY="200"/>
</AnchorPane>

更新

这很管用。但是,一旦我们设置回调事件处理程序,图标图像似乎就会丢失

是的,看起来如果您创建自己的单元工厂,还需要在单元工厂内手动设置图形。这是因为如果在树项上设置了图形,默认树项单元格工厂将从树项中获取图形,而此逻辑不会出现在自定义单元格工厂中,除非您在那里对其进行编码

我更新了示例解决方案中的代码,以显示如何在自定义单元工厂生成的树单元上设置图形。更新后的代码从支持树单元的模型中获取图形图像,但如果首选,它同样可以从树项的图形属性中检索图形图像。要从树项中获取图形,请使用blacks0ul建议的以下代码:

TreeItem<Pair<URIImpl, String>> item = getTreeItem();
if (item != null && item.getGraphic() != null) { 
  setGraphic(item.getGraphic()); 
} 
TreeItem-item=getTreeItem();
如果(item!=null&&item.getGraphic()!=null){
setGraphic(item.getGraphic());
} 

非常感谢@jewelsea!!这很管用。但是,一旦我们设置回调事件处理程序,图标图像似乎就会丢失。通过图标图像,我指的是ImageView实例,我添加了一些根级别(子根级别)树元素。更新了解决潜在图标图像问题的解决方案。我使用的URIImpl是一个自定义库类,不可扩展。也许我已经将URIImpl封装为一个超类的字段。非常感谢您提供完整的解决方案!我想没有其他方法可以从更新中获取图像。我指的是那些在初始化过程中被注入树元素的。因为,现在我们试图通过自定义字段而不是使用TreeItem实例来解决这个问题。找到了一个没有封装的可能解决方法。以下是updateItem方法中的内容。,
TreeItem-item=getTreeItem();如果(item!=null&&item.getGraphic()!=null){setGraphic(item.getGraphic());}
import javafx.scene.image.Image;

class URIImpl {
  private final String uri;
  private final String domain;
  private       Image  image;

  public URIImpl(String uri, String domain) {
    this.uri    = uri;
    this.domain = domain;
  }

  public String getUri() {
    return uri;
  }

  public String getDomain() {
    return domain;
  }

  public Image getImage() {
    if (image == null) {
      image = new Image("https://plus.google.com/_/favicon?domain=" + getDomain());
    }

    return image;
  }

  @Override
  public String toString() {
    return "URIImpl{" + "uri->" + uri + '}';
  }    
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns:fx="http://javafx.com/fxml" fx:controller="tests.treesample.TreeController">
    <TreeView fx:id="treeView" layoutX="0" layoutY="0" prefHeight="193.0" prefWidth="471.0" />
    <Label    fx:id="clickedPair" layoutX="0" layoutY="200"/>
</AnchorPane>
TreeItem<Pair<URIImpl, String>> item = getTreeItem();
if (item != null && item.getGraphic() != null) { 
  setGraphic(item.getGraphic()); 
}