codeNoob
codeNoob

Reputation: 21

JavaFX - Display Nodes at specific row and column in gridpane

I created an UI with JavaFX but have some problems with the layout. Basically I created a gridpane with a bunch of nodes. Here's the basic grid with the lines visible:

enter image description here

This is how I add all the nodes:

 lEncoderName.setMinHeight(0);
    fxEncoderName.setMinHeight(0);
    addRow(0, lEncoderName, fxEncoderName);
    getRowConstraints().add(new RowConstraints(ROW_HEIGHT));
    lNodeType.setMinHeight(0);
    fxNodeType.setMinHeight(0);
    addRow(1, lNodeType, fxNodeType);
    getRowConstraints().add(new RowConstraints(ROW_HEIGHT));

    // MIDI
    lMidiType.setMinHeight(0);
    fxMidiType.setMinHeight(0);
    addRow(getRowCount(), lMidiType, fxMidiType);
    getRowConstraints().add(new RowConstraints(ROW_HEIGHT));
    lMidiName.setMinHeight(0);
    fxMidiName.setMinHeight(0);
    addRow(getRowCount(), lMidiName, fxMidiName);
    getRowConstraints().add(new RowConstraints(ROW_HEIGHT));
    lDumpPos.setMinHeight(0);
    fxDumpPos.setMinHeight(0);
    addRow(getRowCount(), lDumpPos, fxDumpPos);
    getRowConstraints().add(new RowConstraints(ROW_HEIGHT));

and so on... My problem is I want to display nodes at specific row and colum indexes, but I don't know how. For example here, I added a bunch of nodes before my "Value Type" Label, there's the space. Depending on selections, the nodes show. But I want if they do not show, to move my nodes to different indexes in the grid. So the "Value Nodes" should be right underneath "Editbuffer Position":

enter image description here

Basically I'm searching for a method to display nodes at a new row and column than in the order I added them, without destroying the grid.

Upvotes: 0

Views: 317

Answers (1)

Sai Dandem
Sai Dandem

Reputation: 9959

Firstly, I assume you have the references to the nodes that you need to hide.

One way to address this issue without removing the nodes from the GridPane, is to :

  • Turn off the visibility & managed property of the nodes in the row
  • And reconfigure the rowIndex of all the nodes in the grid pane.

Below is the quick demo of the logic which I mentioned. enter image description here

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class DisplayGridPaneNodesDemo extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        List<Node[]> rows = new ArrayList<>();

        ToggleGroup tg = new ToggleGroup();
        RadioButton allBtn = new RadioButton("All");
        allBtn.setToggleGroup(tg);
        allBtn.setSelected(true);
        allBtn.setOnAction(e->displayRows(rows,i->true));

        RadioButton evenBtn = new RadioButton("Even");
        evenBtn.setToggleGroup(tg);
        evenBtn.setOnAction(e->displayRows(rows,i->i%2==0));

        RadioButton oddBtn = new RadioButton("Odd");
        oddBtn.setToggleGroup(tg);
        oddBtn.setOnAction(e->displayRows(rows,i->i%2!=0));

        HBox row = new HBox(allBtn, evenBtn,oddBtn);
        row.setSpacing(10);

        GridPane gridPane = new GridPane();
        gridPane.setGridLinesVisible(true);
        gridPane.setVgap(5);
        for(int i=0;i<10;i++){
            Label c1 = new Label("Row "+i+" Col 0");
            c1.setPadding(new Insets(10));
            Label c2 = new Label("Row "+i+" Col 1");
            c2.setPadding(new Insets(10));
            gridPane.addRow(i,c1,c2);
            Node[] nodes = {c1,c2};
            rows.add(nodes);
        }

        VBox root = new VBox(row, gridPane);
        root.setSpacing(10);
        root.setPadding(new Insets(10));
        Scene scene = new Scene(root, 320,550);
        stage.setScene(scene);
        stage.setTitle("Display Nodes in GridPane");
        stage.show();
    }

    private void displayRows(List<Node[]> rows, Predicate<Integer> isVisible) {
        // Start rowIndex from 0
        IntegerProperty rowIndex = new SimpleIntegerProperty();

        // Loop through all the rows
        for(int i = 0; i<rows.size(); i++){
            // Check if the row needs to be visible or not
            boolean visible = isVisible.test(i);
            Node[] nodes = rows.get(i);

            // Loop through all the nodes in the row and set the visibility and managed
            Stream.of(nodes).forEach(n->{
                n.setVisible(visible);
                n.setManaged(visible);
                // If the row needs to be visible , set the rowIndex to the nodes in the row.
                // YOU DON'T NEED TO WORRY ABOUT THE 'rowIndex' OF INVISIBLE NODES ;-)
                if(visible) {
                    GridPane.setRowIndex(n, rowIndex.get());
                }
            });

            // Increment the rowIndex if we show the current row.
            if(visible){
                rowIndex.set(rowIndex.get()+1);
            }
        }
    }
}

Upvotes: 2

Related Questions