JavaFX setPrefSize не меняет размер vBox - PullRequest
1 голос
/ 09 марта 2020

Я очень новичок в JavaFX и сталкиваюсь с этой проблемой: я хочу сделать макет следующим образом: Что мне нужно

И вот что у меня есть: введите изображение описание здесь

Кажется, что я пробовал много разных макетов, и я просто не могу сделать это правильно. Я закончил с VBox'ами, и это лучшее, что я могу получить. Несмотря на то, что я описал размер «vBox2» с «PrefSize» как половину всей сцены, он не реагирует вообще.

Это мой код:

    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {

        // Create a border pane
        BorderPane pane = new BorderPane();

         // Place nodes in the pane
        pane.setLeft(getVBox());
        pane.setBottom(getVBox2());
        pane.setRight(getVBox3());

        // Create a scene and place it in the stage
        Scene scene = new Scene(pane, 1000,800);
        primaryStage.setTitle("ShowHBoxVBox"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage
    }

    private VBox getVBox() {
        VBox vBox = new VBox(15);
        vBox.setPadding(new Insets(15, 5, 5, 5));
        vBox.getChildren().add(new Label("vbox"));

        Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
            new Label("CSCI 2410"), new Label("CSCI 3720")};

        for (Label course : courses) {
            VBox.setMargin(course, new Insets(0, 0, 0, 15));
            vBox.getChildren().add(course);
        }
        vBox.setStyle("-fx-border-style: solid inside;");
        vBox.setPrefSize(500, 400);

        return vBox;
    }

    private VBox getVBox2() {
        VBox vBox2 = new VBox(15);
        vBox2.setPadding(new Insets(15, 5, 5, 5));
        vBox2.getChildren().add(new Label("Vbox2"));

        Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
            new Label("CSCI 2410"), new Label("CSCI 3720")};

        for (Label course : courses) {
            VBox.setMargin(course, new Insets(5, 5, 5, 15));
            vBox2.getChildren().add(course);
        }
        vBox2.setStyle("-fx-border-style: solid inside;");
        vBox2.setPrefSize(500, 400);

        return vBox2;
    }

    private VBox getVBox3() {
        VBox vBox3 = new VBox(15);
        vBox3.setPadding(new Insets(15, 5, 5, 5));
        vBox3.getChildren().add(new Label("vbox3"));

        Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
            new Label("CSCI 2410"), new Label("CSCI 3720")};

        for (Label course : courses) {
            VBox.setMargin(course, new Insets(0, 0, 0, 15));
            vBox3.getChildren().add(course);
        }
        vBox3.setStyle("-fx-border-style: solid inside;");
        vBox3.setPrefSize(500, 800);

        return vBox3;
    }

}

Я не могу использовать F XML или ввести его в CSS.

Спасибо за любые советы.

Ответы [ 2 ]

0 голосов
/ 09 марта 2020

Общий процесс для панели макета (такой как VBox или BorderPane) для размещения дочерних узлов выглядит следующим образом:

  1. Запросите у дочерних узлов их минимальный, максимальный и предпочтительные размеры
  2. Вычислить позицию и размер, который будет выделен для каждого дочернего узла, придерживаясь его собственной политики компоновки и прилагая все усилия для соблюдения минимального, предпочтительного и максимального размеров дочерних узлов

  3. Запросить, чтобы дочерние узлы выполнили свой собственный макет, выделив размеры, рассчитанные для каждого

Не всегда возможно соблюдать все мин / макс / pref ограничения дочерних узлов; например, если сумма минимальных высот всех дочерних элементов VBox больше, чем высота самого VBox, просто невозможно разместить всех дочерних элементов в макете. И наоборот, если высота VBox больше, чем сумма всех предпочтительных высот дочерних элементов, будет как-то выделено дополнительное вертикальное пространство. Большинство панелей макета имеют параметры, которые настраивают, как обрабатывать такие ситуации: некоторые из этих параметров применяются ко всей панели макета, другие применяются для каждого ребенка.

Политика макета для BorderPane по существу следующим образом:

  • Узлам top и bottom выделяется полная ширина BorderPane, и каждый получает свою предпочтительную высоту. Эти узлы расположены по всей ширине панели границ, сверху и снизу соответственно. Это та часть, которая заставляет BorderPane вести себя не так, как вам нужно.
  • Узлам left и right выделяется полная высота BorderPane, меньше высота узлов top и bottom, и каждый получает свою предпочтительную ширину. Они расположены слева и справа от границы, соответственно, ниже top и выше bottom узлов.
  • Узел center получает все оставшееся пространство.

Это корректируется, если результирующие размеры нарушают минимальный или максимальный размеры узлов, если это возможно.

Таким образом, компоновка вашего изображения точно соответствует ожидаемой; vbox2 получает полную ширину и предпочитаемую высоту; vbox получает предпочитаемую ширину и оставшуюся высоту панели границы, а vbox3 получает оставшееся пространство.

Вы можете в основном добиться того, что вы ищете здесь, поместив vbox и vbox2 в VBox их собственных, и поместив это VBox слева от панели границ; затем поместите vbox3 в центр (правое тоже сработало бы):

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Layout extends Application {
    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {

        // Create a border pane
        BorderPane pane = new BorderPane();

         // Place nodes in the pane

        VBox left = new VBox(getVBox(), getVBox2());
        pane.setLeft(left);
        pane.setCenter(getVBox3());

        // Create a scene and place it in the stage
        Scene scene = new Scene(pane);
        primaryStage.setTitle("ShowHBoxVBox"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage
    }

    private VBox getVBox() {
        VBox vBox = new VBox(15);
        vBox.setPadding(new Insets(15, 5, 5, 5));
        vBox.getChildren().add(new Label("vbox"));

        Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
            new Label("CSCI 2410"), new Label("CSCI 3720")};

        for (Label course : courses) {
            VBox.setMargin(course, new Insets(0, 0, 0, 15));
            vBox.getChildren().add(course);
        }
        vBox.setStyle("-fx-border-style: solid inside;");
        vBox.setPrefSize(500, 400);

        return vBox;
    }

    private VBox getVBox2() {
        VBox vBox2 = new VBox(15);
        vBox2.setPadding(new Insets(15, 5, 5, 5));
        vBox2.getChildren().add(new Label("Vbox2"));

        Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
            new Label("CSCI 2410"), new Label("CSCI 3720")};

        for (Label course : courses) {
            VBox.setMargin(course, new Insets(5, 5, 5, 15));
            vBox2.getChildren().add(course);
        }
        vBox2.setStyle("-fx-border-style: solid inside;");
        vBox2.setPrefSize(500, 400);

        return vBox2;
    }

    private VBox getVBox3() {
        VBox vBox3 = new VBox(15);
        vBox3.setPadding(new Insets(15, 5, 5, 5));
        vBox3.getChildren().add(new Label("vbox3"));

        Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
            new Label("CSCI 2410"), new Label("CSCI 3720")};

        for (Label course : courses) {
            VBox.setMargin(course, new Insets(0, 0, 0, 15));
            vBox3.getChildren().add(course);
        }
        vBox3.setStyle("-fx-border-style: solid inside;");
        vBox3.setPrefSize(500, 800);

        return vBox3;
    }

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

}

Вы не указали, как вы будете себя вести при изменении размера окна, но область "center" по существу будет более «отзывчивый», чем левый.

Исходное окно выглядит так:

enter image description here

0 голосов
/ 09 марта 2020

Самое простое решение вашей проблемы, которое я могу придумать, это построить два HBox и поместить в них VBox. Для примера о том, как: Себастьян Дамм создал этот простой: https://www.javacodegeeks.com/2012/07/javafx-20-layout-panes-hbox-and-vbox.html

    import javafx.application.Application;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;


/**
 *
 * Created on: 20.03.2012
 * @author Sebastian Damm
 */
public class HBoxandVBoxExample extends Application
{
    @Override
    public void start(Stage primaryStage) throws Exception
    {                
        HBox hbox = new HBox(50);
        hbox.setAlignment(Pos.CENTER); // default TOP_LEFT

        VBox vbox1 = new VBox();
        vbox1.setAlignment(Pos.BOTTOM_CENTER);
        vbox1.setStyle("-fx-border-style: solid;"
                + "-fx-border-width: 1;"
                + "-fx-border-color: black");

        VBox vbox2 = new VBox(10);
        vbox2.setAlignment(Pos.CENTER);
        vbox2.setStyle("-fx-border-style: solid;"
                + "-fx-border-width: 1;"
                + "-fx-border-color: black");

        VBox vbox3 = new VBox(20);
        vbox3.setAlignment(Pos.TOP_CENTER);
        vbox3.setStyle("-fx-border-style: solid;"
                + "-fx-border-width: 1;"
                + "-fx-border-color: black");

        for (int i = 0; i < 5; i++)
        {
            Button bt = new Button("Button " + (i+1));
            Button bt2 = new Button("Button " + (i+1)); // unfortunately there´s no "clone" or "copy" method
            Button bt3 = new Button("Button " + (i+1));

            vbox1.getChildren().add(bt);
            vbox2.getChildren().add(bt2);
            vbox3.getChildren().add(bt3);
        }

        hbox.getChildren().addAll(vbox1, vbox2, vbox3);
        Scene scene = new Scene(hbox, 350, 250); // the hbox is the root node

        primaryStage.setTitle("HBox and VBox Example");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args)
    {
        Application.launch(args);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...