如何均匀分布 JavaFX VBox 的元素

Posted

技术标签:

【中文标题】如何均匀分布 JavaFX VBox 的元素【英文标题】:how to evenly distribute elements of a JavaFX VBox 【发布时间】:2017-04-14 12:14:44 【问题描述】:

我正在使用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;
    

【问题讨论】:

【参考方案1】:

您可以做的是在每个标签之前和之后添加“spacers”,由于VBox.setVgrow(Node child, Priority value)Priority.ALWAYS 作为优先级值,该标签将始终根据可用空间增大或缩小。

这是创建“spacer”的方法

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”分隔

【讨论】:

以上是关于如何均匀分布 JavaFX VBox 的元素的主要内容,如果未能解决你的问题,请参考以下文章

如何在 javafx 中设置带有子窗口的菜单栏?

如何将元素水平均匀分布?

JavaFX 样式所有相同类型的节点,例如,VBox

将一个vBox置于JavaFx中BorderPane的中间

在JavaFX中添加自定义组件

如何使用弹性框均匀分布图像和子元素?