user2909180
user2909180

Reputation: 215

Creating a dynamic GridPane (add and remove rows)

So I need to add and delete Rows in a GridPane when selecting or deselecting a MenuItem.

So when selecting a MenuItem it should add 1 or 2 rows in the existing GridPane. When deselecting it should remove 1 or 2 of the rows.

There is always a fixed row that cannot be removed. the added or deleted rows should be added or removed above this fixed row.

For example:

Add row:

added ---------  

added ---------  

fixed ---------

Remove row:

removed 

removed 

fixed ----------- 

I know how to handle the actions for the MenuItems. I only need help with the dynamic Grid Pane.

There is a built in function addRow for GridPanes, maybe its the one to use. How can I solve this? Thanks! All tips appreciated.

Upvotes: 3

Views: 3920

Answers (2)

user2909180
user2909180

Reputation: 215

Many thanks! So I had some problems to get it to work, so I changed it into 2 separate buttons, 1 show and 1 hide. And put an event action on the buttons. It does the right thing on the show button. On hide it removes the 2 rows but keeps 1 row above, not sure why. Then it's stuck in exception.

@FXML
private void add_act(ActionEvent event) {
    SimpleBooleanProperty expanded = new SimpleBooleanProperty(true);

        // Just to see that the lines are actually added
        grid.setGridLinesVisible(true);

        grid.getRowConstraints().add(new RowConstraints(30)); //add 1 row
        grid.getRowConstraints().add(new RowConstraints(30)); //add 1 row

        grid.addRow(2, new Label("I am fixed!")); //on index 2 write label

        show.setOnAction((e) -> {
            expanded.set(expanded.not().get());
        });

}

@FXML
private void hide_act(ActionEvent event) {
    SimpleBooleanProperty expanded = new SimpleBooleanProperty(true);

        // Just to see that the lines are actually added
        grid.getRowConstraints().get(0).setMaxHeight(0);
        grid.getRowConstraints().get(1).setMaxHeight(0);

        show.setOnAction((e) -> {
            expanded.set(expanded.not().get());
        });
}

And also I need to keep track on which row index is added or removed. Probably done with: setRowIndex(button, 1), setColumnIndex(button, 2), setConstraints(label, 3, 1); // column=3 row=1

Upvotes: 0

DVarga
DVarga

Reputation: 21799

This answer is about to hide and show rows of a GridPane rather than adding and removing them, as I think it is more reasonable to not create new objects every time when the MenuItem is selected.

I have made you an example that contains a GridPane and a Button (rather than a MenuItem but it has the same function here). On the press of the button the first two row of the GridPane is shown or hidden.

I have used the RowConstraints class: I have added three RowConstraints for the GridPane and then on button press the maxHeightProperty of the first two constraints is set to 0 (hide) or 30 (show).

public class Main extends Application {

    private SimpleBooleanProperty expanded = new SimpleBooleanProperty(true);

    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root,400,400);


            VBox vbox = new VBox();


            GridPane grid = new GridPane();
            // Just to see that the lines are actually added
            grid.setGridLinesVisible(true);
            grid.setPrefWidth(200);

            grid.getRowConstraints().add(new RowConstraints(30));
            grid.getRowConstraints().add(new RowConstraints(30));

            grid.addRow(2, new Label("I am fixed!"));
            grid.getRowConstraints().add(new RowConstraints(30));



            Button showOrHideButton = new Button();
            showOrHideButton.setOnAction((e) -> {
                expanded.set(expanded.not().get());
            });


            vbox.getChildren().addAll(showOrHideButton, grid);

            expanded.addListener((obs, oldVal, newVal) -> {
                if(newVal) {
                    grid.getRowConstraints().get(0).setMaxHeight(30);
                    grid.getRowConstraints().get(1).setMaxHeight(30);
                    showOrHideButton.setText("Hide");
                } else {
                    grid.getRowConstraints().get(0).setMaxHeight(0);
                    grid.getRowConstraints().get(1).setMaxHeight(0);
                    showOrHideButton.setText("Show");
                }
            });

            expanded.set(false);


            root.setCenter(vbox);

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

It produces something like this:

enter image description here

Upvotes: 1

Related Questions