Dynamically add elements to a fixed-size GridPane in JavaFX

前端 未结 2 412
花落未央
花落未央 2021-01-15 00:03

I would like to display a grid containing a various number of rectangles in JavaFX. It is important that this grid cannot be resized.

I chose the GridPane

相关标签:
2条回答
  • 2021-01-15 00:31

    Thanks a lot for your answer. TilePanes are indeed a lot easier to use, although what you've written does not completely answer my question.

    I wanted to have a pane in which the children would resize, and not the pane itself. It seems setting the maxSize and prefSize doesn't have any effect.

    EDIT: I managed to do it using two JavaFX Property in my GridDisplay class, corresponding to the fixed height and width of my grid:

    public class GridDisplay {
        private ReadOnlyDoubleProperty heightProperty;
        private ReadOnlyDoubleProperty widthProperty;
    
        ...
    }
    

    Then I assign to these members the values corresponding to the desired fixed size in the constructor. The size of the children inside the grid correspond to a fraction of the height and width of the grid, depending on the number of rows and columns. Here's what my updateDisplay() looks like:

    public void updateDisplay() {
        gridPane.getChildren().clear();
        for (int i = 0; i < nbColumn; i++) {
            for (int j = 0; j < nbRow; j++) {
                Rectangle rectangle = new Rectangle(100, 100);
                //Binding the fraction of the grid size to the width
                //and heightProperty of the child
                rectangle.widthProperty().bind(widthProperty.divide(nbColumn));
                rectangle.heightProperty().bind(heightProperty.divide(nbRow));
                gridPane.add(rectangle, i, j);
             }
        }
    }
    
    0 讨论(0)
  • 2021-01-15 00:38

    Seems like a TilePane is a better fit for this use case than a GridPane.

    2by4 3by2

    import javafx.application.Application;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.TilePane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    
    // java 8 code
    public class DynamicTiles extends Application {
    
        //Class containing grid (see below)
        private GridDisplay gridDisplay;
    
        //Class responsible for displaying the grid containing the Rectangles
        public class GridDisplay {
    
            private static final double ELEMENT_SIZE = 100;
            private static final double GAP = ELEMENT_SIZE / 10;
    
            private TilePane tilePane = new TilePane();
            private Group display = new Group(tilePane);
            private int nRows;
            private int nCols;
    
            public GridDisplay(int nRows, int nCols) {
                tilePane.setStyle("-fx-background-color: rgba(255, 215, 0, 0.1);");
                tilePane.setHgap(GAP);
                tilePane.setVgap(GAP);
                setColumns(nCols);
                setRows(nRows);
            }
    
            public void setColumns(int newColumns) {
                nCols = newColumns;
                tilePane.setPrefColumns(nCols);
                createElements();
            }
    
            public void setRows(int newRows) {
                nRows = newRows;
                tilePane.setPrefRows(nRows);
                createElements();
            }
    
            public Group getDisplay() {
                return display;
            }
    
            private void createElements() {
                tilePane.getChildren().clear();
                for (int i = 0; i < nCols; i++) {
                    for (int j = 0; j < nRows; j++) {
                        tilePane.getChildren().add(createElement());
                    }
                }
            }
    
            private Rectangle createElement() {
                Rectangle rectangle = new Rectangle(ELEMENT_SIZE, ELEMENT_SIZE);
                rectangle.setStroke(Color.ORANGE);
                rectangle.setFill(Color.STEELBLUE);
    
                return rectangle;
            }
    
        }
    
        @Override
        public void start(Stage primaryStage) {
    
            //Represents the grid with Rectangles
            gridDisplay = new GridDisplay(2, 4);
    
            //Fields to specify number of rows/columns
            TextField rowField = new TextField("2");
            TextField columnField = new TextField("4");
    
            //Function to set an action when text field loses focus
            buildTextFieldActions(rowField, columnField);
    
            HBox fields = new HBox(10);
            fields.getChildren().add(rowField);
            fields.getChildren().add(new Label("x"));
            fields.getChildren().add(columnField);
    
            BorderPane mainPanel = new BorderPane();
            mainPanel.setCenter(gridDisplay.getDisplay());
            mainPanel.setTop(fields);
    
            Scene scene = new Scene(mainPanel, 1000, 800);
            primaryStage.setTitle("Test grid display");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    
        private void buildTextFieldActions(final TextField rowField, final TextField columnField) {
            rowField.focusedProperty().addListener((ov, t, t1) -> {
                if (!t1) {
                    if (!rowField.getText().equals("")) {
                        try {
                            int nbRow = Integer.parseInt(rowField.getText());
                            gridDisplay.setRows(nbRow);
                        } catch (NumberFormatException nfe) {
                            System.out.println("Please enter a valid number.");
                        }
                    }
                }
            });
    
            columnField.focusedProperty().addListener((ov, t, t1) -> {
                if (!t1) {
                    if (!columnField.getText().equals("")) {
                        try {
                            int nbColumn = Integer.parseInt(columnField.getText());
                            gridDisplay.setColumns(nbColumn);
                        } catch (NumberFormatException nfe) {
                            System.out.println("Please enter a valid number.");
                        }
                    }
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题