Javafx-2 – Java FX 2 treeview model reference

I tried to get treeitems valueproperty during the onmouseclick event I have a treeview of the following types:

@FXML
private TreeView<Pair<URIImpl,String>> myTreeview;

Fxml is as follows:

<TreeView fx:id="myTreeview" onMouseClicked="#myTreeview_Clicked" 
        prefHeight="551.0" prefWidth="166.0"
        AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" 
        AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />

I want to retrieve my model (paired instance) when I click

void myTreeview_Clicked(MouseEvent event) {
    if(event.getTarget() instanceof ...) {
        // Fetch Target
    }
}

In my case, the target object is label text. As far as I know, it does not contain encapsulated model references Can anyone suggest? This seems to be a very basic feature One way binding... With some kind of reference I'm not going to edit treeitems

This post seems to be similar to the problem: model identifier for node in JavaFX 2 treeitem

thank you

Solution

The key is to define a cell factory on treeview and add a mouse click event handler to the tree cell in the cell factory The mouse click event handler so defined will have full access to model objects that support tree cells and can be used to perform the required operations

In the following example, when the user clicks a cell in the tree, the click handler extracts information from the underlying model project related to the clicked cell and renders the information to a label under the tree

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

}

URIImpl. java

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 + '}';
  }    
}

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>

to update

Yes, it seems that if you create your own cell factory, you also need to manually set up graphics in the cell factory This is because the default tree item cell factory will get graphics from the tree item. If graphics have been set on the tree item, this logic will not appear in the custom cell factory unless you code there

I updated the code in the sample solution to show how to set up graphics on tree cells generated by the custom cell factory The updated code gets a graphical image from a model that supports tree cells, but if preferred, it can be retrieved from the graphical properties of the tree item To get graphics from treeitem, use the following code recommended by blacks0ul:

TreeItem<Pair<URIImpl,String>> item = getTreeItem();
if (item != null && item.getGraphic() != null) { 
  setGraphic(item.getGraphic()); 
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>