В Javafx, как установить размер ячейки сетки, доля родительской панели? - PullRequest
0 голосов
/ 19 июня 2019

Я пытаюсь создать gridPane в JavaFx с кружком в нем. Я хочу, чтобы ячейки gridPane использовали все доступное пространство в gridPane. (GridPane находится в центре BorderPane), но ячейки продолжают изменять размер до размеры внутренних объектов. Как заставить клетки использовать все доступное пространство? (и как мне установить радиус круга на долю пространства, доступного в центре BorderPane.

Я новичок в JavaFx, но я пытался использовать Columnconstraints и RowConstraints, чтобы соответствовать моим потребностям. Это не сработало. Я также пытался привязать размер своих объектов в GridPane, чтобы использовать часть размера сцены, но он не работает должным образом, так как он не соответствует плоскости в BorderPane.

public void start(Stage primaryStage) throws Exception{
        BorderPane applicationLayout = new BorderPane();
        primaryStage.setTitle("Multi-level feedback simulator");
        Scene scene = new Scene(applicationLayout, 600, 600);
        primaryStage.setScene(scene);

        //Add the menu Bar
        //MainMenuBar menuBar = new MainMenuBar(primaryStage);
        //applicationLayout.setTop(menuBar);

        //Add the main zone of drawing
        TreeDrawingZone treeDrawingZone = new TreeDrawingZone(primaryStage,applicationLayout,3,3);

        applicationLayout.setCenter(treeDrawingZone);
        primaryStage.show();
        primaryStage.setMaximized(true);

    }

Код GridPane с ограничениями. Большая часть конструктора создает линии и круги для отображения дерева. Функции рисования: createLine () и createCircle ()

 public class TreeDrawingZone extends Parent {
    private GridPane drawingZoneLayout;
    private Stage stage;
    private int columnNumber;
    private int rowNumber;
    private Pane rootPane;
    private List<Pair<Integer,Integer>> circlePositions;

    public TreeDrawingZone(Stage stage,Pane rootPane, int treeHeight, int childrenPerNode){
        this.stage = stage;
        drawingZoneLayout = new GridPane();
        columnNumber = 2*(int)Math.pow(childrenPerNode,treeHeight-1)-1;
        rowNumber = 2*treeHeight-1;
        circlePositions = new ArrayList<>();
        this.rootPane = rootPane;
        //TODO Use the correct height of the borderLayout (maybe with a upper level layout)
        System.out.println(columnNumber);
        System.out.println(rowNumber);
        //column Constraints
        for(int i = 1 ; i <= columnNumber ; i++){
            ColumnConstraints columnConstraints = new ColumnConstraints();
            columnConstraints.setPercentWidth((double) 100/columnNumber);
            columnConstraints.setFillWidth(true);
            drawingZoneLayout.getColumnConstraints().add(columnConstraints);
        }

        //row Constraints
        for(int i = 1 ; i <= rowNumber ; i++){
            RowConstraints rowConstraints = new RowConstraints();
            rowConstraints.setPercentHeight((double) 100/rowNumber);
            rowConstraints.setFillHeight(true);
            drawingZoneLayout.getRowConstraints().add(rowConstraints);
        }

        //Tree Representation
        //Base Line
        List<Integer> circleLineRepartition = new ArrayList<>();
        for(int i = 0 ; i < columnNumber; i ++){
            if(i % 2 == 0){
                circleLineRepartition.add(i);
            }
        }
        System.out.println(circleLineRepartition);
        //Creation of the grid line per line
        for(int i = rowNumber-1 ; i >=0 ; i-=2){
            if(i % 2 == 0) {
                //Case of the line with circles
                for (Integer circlePosition : circleLineRepartition) {
                    Pane circlePane;
                    if (i == 0) {
                        circlePane = createCircle(true, false);
                    } else if (i == rowNumber - 1) {
                        circlePane = createCircle(false, true);
                    } else {
                        circlePane = createCircle();
                    }
                    drawingZoneLayout.add(circlePane, circlePosition, i);
                    circlePositions.add(new Pair<>(circlePosition, i));
                }
                List<Integer> upperCircleLineRepartition;
                //Create the lines
                //The following block enumerates the different cases to create the lines between the dotes
                try {
                    upperCircleLineRepartition = getoddlyRepartedCenters(childrenPerNode, circleLineRepartition);
                    if (i > 0) {
                        int minPosition = circleLineRepartition.get(0);
                        int maxPosition = circleLineRepartition.get(circleLineRepartition.size() - 1);
                        int position = 0;
                        boolean drawHorizontal = true;
                        int linkedNodeCount = 0;
                        for (int j = minPosition; j <= maxPosition; j++) {
                            Pane linesPane;
                            if (j == circleLineRepartition.get(position) && minPosition != maxPosition) {
                                //Update the number of linked Nodes
                                if(drawHorizontal) {
                                    linkedNodeCount += 1;
                                    if(linkedNodeCount == childrenPerNode)
                                        drawHorizontal = false;
                                }else{
                                    linkedNodeCount = 1;
                                    drawHorizontal = true;
                                }
                                //First element
                                if (linkedNodeCount == 1) {
                                    if(upperCircleLineRepartition.contains(j)){
                                        linesPane = createLines(LineDirection.NORTH,LineDirection.SOUTH,LineDirection.EAST);
                                    }else {
                                        linesPane = createLines(LineDirection.SOUTH, LineDirection.EAST);
                                    }
                                }
                                //Last element
                                else if (linkedNodeCount == childrenPerNode) {
                                    if(upperCircleLineRepartition.contains(j)){
                                        linesPane = createLines(LineDirection.NORTH,LineDirection.SOUTH,LineDirection.WEST);
                                    }else {
                                        linesPane = createLines(LineDirection.WEST, LineDirection.SOUTH);
                                    }
                                }//bridge with under and upper level
                                else if(upperCircleLineRepartition.contains(j)) {
                                    linesPane = createLines(LineDirection.SOUTH, LineDirection.NORTH, LineDirection.EAST, LineDirection.WEST);
                                }
                                //other children
                                else{
                                    linesPane = createLines(LineDirection.SOUTH, LineDirection.EAST, LineDirection.WEST);
                                }
                                position++;
                            }
                            //Only one child
                            else if (minPosition == maxPosition) {
                                linesPane = createLines(LineDirection.SOUTH, LineDirection.NORTH);
                            }
                            //Bridge between children
                            else {
                                if(drawHorizontal) {
                                    if (upperCircleLineRepartition.contains(j)) {
                                        linesPane = createLines(LineDirection.NORTH, LineDirection.EAST, LineDirection.WEST);
                                    } else {
                                        linesPane = createLines(LineDirection.WEST, LineDirection.EAST);
                                    }
                                }else{
                                    linesPane = createLines();
                                }
                            }

                            drawingZoneLayout.add(linesPane, j, i - 1);
                        }
                    }
                    circleLineRepartition = new ArrayList<>(upperCircleLineRepartition);
                } catch (Exception e) {
                    System.out.println("Invalid line given");
                }
            }
        }
         drawingZoneLayout.setMaxSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
        //TODO remove GridLines after debug
        drawingZoneLayout.setGridLinesVisible(true);
        this.getChildren().add(drawingZoneLayout);
    }


    private Pane createCircle(){
        return createCircle(false,false);
    }

    private Pane createCircle(boolean isRoot, boolean isLeaf){
        Pane circlePane = new Pane();
        Circle circle = new Circle();
        circle.centerXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
        circle.centerYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
        circle.radiusProperty().bind(Bindings.min(stage.widthProperty().divide(columnNumber).divide(2),stage.heightProperty().divide(rowNumber).divide(2)));
        circlePane.getChildren().add(circle);
        if(!isLeaf) {
            circlePane.getChildren().add(createLines(LineDirection.SOUTH));
        }
        if(!isRoot){
            circlePane.getChildren().add(createLines(LineDirection.NORTH));
        }
        return circlePane;
    }

    private Pane createLines(LineDirection ... directions){
        Pane linesGroup = new Pane();
        for(LineDirection direction : directions){
            linesGroup.getChildren().add(createLine(direction));
        }
        return linesGroup;
    }

    private Line createLine(LineDirection direction){
        Line line = new Line();
        if(direction == LineDirection.EAST || direction == LineDirection.WEST){
            line.startYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
            line.endYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
            line.startXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
            if(direction == LineDirection.EAST){
                line.endXProperty().bind(stage.widthProperty().divide(columnNumber));
            }
            else{
                line.setEndX(0);
            }
        }
        else{
            line.startXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
            line.endXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
            line.startYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
            if(direction == LineDirection.NORTH){
                line.setEndY(0);
            }else{
                line.endYProperty().bind(stage.heightProperty().divide(rowNumber));
            }
        }
        line.setStrokeWidth(1);
        line.setFill(null);
        line.setStroke(Color.BLACK);
        return line;
    }

    private int getCenter(List<Integer> childrenNodesPosition) throws Exception {
        if (childrenNodesPosition.size() == 0){
            throw new Exception("Tried to get the center of an empty list");
        }else{
            int sum = 0;
            for(int childNodePosition : childrenNodesPosition){
                sum += childNodePosition;
            }
            return sum/childrenNodesPosition.size();
        }
    }

    private List<Integer> getoddlyRepartedCenters(int nodeNumberPerParent, List<Integer> childrenNodesPosition) throws Exception {
        int parentNumber = childrenNodesPosition.size()/nodeNumberPerParent;
        int nextPosition = 0;
        List<Integer> regularParentCenters = new ArrayList<>(parentNumber);
        for(int i = 0 ; i < parentNumber ; i++){
            regularParentCenters.add(getCenter(childrenNodesPosition.subList(nextPosition,nextPosition + nodeNumberPerParent)));
            nextPosition = nextPosition + nodeNumberPerParent;
        }
        return regularParentCenters;
    }

}


Результат, который я хочу исправить

...