10

For an application I am developing, I need the user to input a number of rows of data. The exact number is variable and the users should be able to add rows themselves too. I've got this all working now with a JavaFX Dialog, apart from the fact that when you add rows, the Dialog is not resized accordingly. Is there a way to get the Dialog to resize automatically when a row is added?

Below is a demo application with a sample test application with a Dialog similar to what I want.

package test_dialog;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Test_Dialog extends Application {

    class ScalableDialog extends Dialog<String> {

        int nrRows = 2;

        public ScalableDialog() {

            // We are resizable
            setResizable(true);

            // Set up the grid pane.
            GridPane grid = new GridPane();
            grid.setHgap(10);
            grid.setVgap(5);
            grid.setMaxWidth(Double.MAX_VALUE);
            grid.setAlignment(Pos.CENTER_LEFT);

            // Set up dialog pane
            DialogPane dialogPane = getDialogPane();
            dialogPane.setHeaderText(null);
            dialogPane.getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
            dialogPane.setContent(grid);

            // Create some fields to start with
            for (int i = 0; i < nrRows; i++) {
                grid.addRow(i, new TextField("Row: " + i));
            }

            // Add button
            final Button buttonAdd = new Button("Add Row");
            buttonAdd.setOnAction((ActionEvent e) -> {
                // Move Button to next row
                GridPane.setRowIndex(buttonAdd, nrRows + 1);
                // Insert new text field row
                grid.addRow(nrRows, new TextField("New: " + nrRows++));
            });
            grid.add(buttonAdd, 0, nrRows);
        }
    }

    @Override
    public void start(Stage primaryStage) {
        Button button = new Button();
        button.setText("Open Dialog");
        button.setOnAction(e -> {
            new ScalableDialog().showAndWait();
        });

        StackPane root = new StackPane();
        root.getChildren().add(button);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Scalable Dialog Test");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}
Hayo Baan
  • 594
  • 5
  • 17
  • Not aware of a simple method in the framework but you are controlling the addition of the new rows, so after you have added the rows, you can manually resize. – Tuxxy_Thang Jul 03 '15 at 13:27

1 Answers1

12

Do

dialogPane.getScene().getWindow().sizeToScene();

on action event handler of "Add" button.
Stage.sizeToScene(), is similar to Swing's jframe.pack(). At the bottom the dialog is being added to some (sub, secondary) stage, and we can get it by getScene().getWindow().

Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
  • why are you sizing to the scene, care to explain a little sir? – Elltz Jul 03 '15 at 14:59
  • Excellent, the `dialogPane.getScene().getWindow().sizeToScene();` did the trick. I found that once you have added more rows that the screen can display, all sorts of strange things happen (at least on a Mac), but I'll hopefully be able to prevent those by adding a scroll pane underneath… – Hayo Baan Jul 03 '15 at 16:00