JavaFX: Laying out Nodes in a Row

Given following layout:

enter image description here

In some cases Field 2 (and the corresponding Labelabove) are invisible and Field 3 and Field 4 shall be moved left accordingly.

My first attempt was to place the elements in a Pane (as I did as well for the screenshot in this example) and recalculate the exact positions of all elements if one is set invisible. This solution is working but it needs lot of maintenance if the element, their sizes or order changes.

In the course of discussing another problem I got the idea to use a HBox to place the fields in it, which would give me auto-spacing.

But using a HBox does not do the trick, because:

  1. As far as I see in a HBox the labels cannot be set above the elements.
  2. If I set an element invisible the other elements won't move left.

Any ideas how to archive my desired behavior?

2 answers

  • answered 2017-10-20 05:14 MBec

    Put each Label with ComboBox/Label into VBox. Then add/remove them from HBox depending on your requirements. Another solution is to put everything into GridPane and add/remove columns.

  • answered 2017-10-20 05:14 fabian

    Making a Node invisible does not remove it from the layout. Removing a node from a parent layout is done by

    1. removing a Node from the child list of the parent or
    2. setting the managed property of the node to false.

    Example showing/hiding a node using the managed property:

    public static void toggleVisibility(Node node) {
        boolean newValue = !node.isVisible();
        node.setVisible(newValue);
    
        // invisible nodes should not be taken into account for HBox layout
        node.setManaged(newValue);
    }
    
    @Override
    public void start(Stage primaryStage) {
        Rectangle rect1 = new Rectangle(100, 100, Color.RED.deriveColor(0, 1, 1, 0.5));
        Rectangle rect2 = new Rectangle(100, 100, Color.GREEN.deriveColor(0, 1, 1, 0.5));
        Rectangle rect3 = new Rectangle(100, 100, Color.BLUE.deriveColor(0, 1, 1, 0.5));
        HBox hbox = new HBox(rect1, rect2, rect3);
    
        Scene scene = new Scene(hbox);
        scene.setOnMouseClicked(evt -> {
            toggleVisibility(rect2);
        });
    
        primaryStage.setScene(scene);
        primaryStage.show();
    }