/** * Creates the node visual. The given {@link ImageView}, {@link Text}, and {@link StackPane} are * inserted into that node visual to display the node's icon, label and nested children, * respectively. The node visual needs to be inserted into the given {@link Group}. * * @param group This node's visual. * @param rect The {@link Rectangle} displaying border and background. * @param iconImageView The {@link ImageView} displaying the node's icon. * @param labelText The {@link Text} displaying the node's label. * @param nestedContentStackPane The {@link StackPane} displaying the node's nested content. */ protected void createNodeVisual( final Group group, final Rectangle rect, final ImageView iconImageView, final Text labelText, final StackPane nestedContentStackPane) { // put image and text next to each other at the top of the node hbox = new HBox(); hbox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); hbox.getChildren().addAll(iconImageView, labelText); // put nested content stack pane below image and text vbox = new VBox(); vbox.setMouseTransparent(true); vbox.getChildren().addAll(hbox, nestedContentStackPane); VBox.setVgrow(nestedContentStackPane, Priority.ALWAYS); // expand box depending on content size vbox.layoutBoundsProperty() .addListener( new ChangeListener<Bounds>() { @Override public void changed( ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) { vbox.setTranslateX(getPadding()); vbox.setTranslateY(getPadding()); rect.setWidth(vbox.getWidth() + 2 * getPadding()); rect.setHeight(vbox.getHeight() + 2 * getPadding()); } }); // place the box below the other visuals group.getChildren().addAll(rect, vbox); }