如何均匀分布JavaFX VBox中的元素

11

我正在使用 VBox 并向其中添加了三个标签。标签之间的垂直间距由 setSpacing() 方法设置。但它是一个固定值,比如说 20。如果我将该值更改为 50,则间隔将增加。但这是硬编码。

我想知道是否有任何预定义的方法可用,以便标签将按(基于VBox高度)均匀分布。如果我调整窗口大小,则应调整标签(即标签之间的间距),以使它们仍然均匀分布(任何两个标签之间具有相同的间距)。

由于 VBox 设置在 BorderPane 的左侧,我希望 "lab0" 在 "Display Line 1","lab1" 在 "Display Line 5","lab2" 在 "Display Line 9"(以对齐方式表示)。如果添加更多的 TextFields,则 "lab2" 应该在最后一个 "Display Line X"。

我的代码在这里...请检查。

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Font;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class MyJavaFx extends Application
{
    public MyJavaFx()
    {
    }

    public void start(Stage primaryStage)
    {
        BorderPane pane = new BorderPane();
        pane.setTop(getRadioButtons());
        pane.setBottom(getPushButtons());
        pane.setLeft(getLeftLabels());
        pane.setRight(getRightLabels());
        pane.setCenter(getTextFields());
        Scene scene=new Scene(pane,1000,800);

        primaryStage.setTitle("Even");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

    FlowPane getRadioButtons()
    {
        FlowPane pane = new FlowPane();
        pane.setPadding(new Insets(10,10,10,10));
        pane.setHgap(10);
        RadioButton rb[]=new RadioButton[3];
        ToggleGroup radioGroup = new ToggleGroup();
        for(int i=0;i<rb.length;i++)
        {
            rb[i] = new RadioButton("Flag "+(i+1));
            rb[i].setToggleGroup(radioGroup);
            pane.getChildren().add(rb[i]);
        }
        rb[0].setSelected(true);
        pane.setAlignment(Pos.CENTER);
        return pane;
    }

    FlowPane getPushButtons()
    {
        FlowPane pane = new FlowPane();
        pane.setPadding(new Insets(10,30,30,10));
        pane.setHgap(10);
        Button rb[]=new Button[3];
        for(int i=0;i<rb.length;i++)
        {
            rb[i] = new Button("but"+i);
            pane.getChildren().add(rb[i]);
        }
        pane.setAlignment(Pos.BOTTOM_RIGHT);
        return pane;
    }
    VBox getLeftLabels()
    {
        VBox pane = new VBox();
        pane.setPadding(new Insets(10,10,10,10));
        pane.setSpacing(20);
        Label ll[]=new Label[3];
        for(int i=0;i<ll.length;i++)
        {
            ll[i] = new Label("lab"+i);
            pane.getChildren().add(ll[i]);
        }
        ll[0].setAlignment(Pos.TOP_LEFT);
        ll[1].setAlignment(Pos.CENTER_LEFT);
        ll[2].setAlignment(Pos.BOTTOM_LEFT);
        pane.setAlignment(Pos.CENTER_LEFT);
        return pane;
    }

    VBox getRightLabels()
    {
        VBox pane = new VBox();
        pane.setPadding(new Insets(10,10,10,10));
        pane.setSpacing(20);
        Label rb[]=new Label[3];
        for(int i=0;i<rb.length;i++)
        {
            rb[i] = new Label("lab"+i);
            pane.getChildren().add(rb[i]);
        }
        pane.setAlignment(Pos.CENTER_RIGHT);
        return pane;
    }

    VBox getTextFields()
    {
        VBox pane = new VBox();
        pane.setPadding(new Insets(10,10,10,10));
        pane.setSpacing(2);
        TextField tf[]=new TextField[9];
        for(int i=0;i<tf.length;i++)
        {
            tf[i] = new TextField("Display Line "+(i+1));

            pane.getChildren().add(tf[i]);
        }
        pane.setAlignment(Pos.CENTER_RIGHT);
        return pane;
    }
}
2个回答

13
你可以在每个标签前后添加“间隔器”,然后使用VBox.setVgrow(Node child, Priority value)方法,将优先级值设置为Priority.ALWAYS,这些间隔器就会根据可用空间自动调整大小。
以下是创建“间隔器”的方法。
private Node createSpacer() {
    final Region spacer = new Region();
    // Make it always grow or shrink according to the available space
    VBox.setVgrow(spacer, Priority.ALWAYS);
    return spacer;
}

那么你的代码将是:

VBox getTextFields()
{
    VBox pane = new VBox();
    pane.setPadding(new Insets(10,10,10,10));
    TextField tf[]=new TextField[9];
    // Add first spacer
    pane.getChildren().add(createSpacer());
    for(int i=0;i<tf.length;i++)
    {
        tf[i] = new TextField("Display Line "+(i+1));
        pane.getChildren().add(tf[i]);
        // Add a spacer after the label
        pane.getChildren().add(createSpacer());
    }
    pane.setAlignment(Pos.CENTER_RIGHT);
    return pane;
}

关于你提出的第二个问题,即你想将标签labXDisplay Line X对齐,最简单的方法是将应在同一行的所有标签放在一个共同的HBox中,并使用如上所述的"spacers"进行分隔。


0

我个人正在寻找一个VBOX,然后我想到了一个解决方案。

对于一个VBOX; 将您的元素设置为固定宽度,这意味着Pref、Max和Min Width相等。然后,在它们之间放置窗格。只需将窗格的Pref宽度设置为最大可能合理的宽度,而其余部分则将max和min留在USE_COMPUTED_SIZE。窗格将根据可用空间增长和缩小,动态地保持元素均匀间隔。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接