在JavaFX中获取节点的高度(生成布局过程)

在JavaFX中获取节点的高度(生成布局过程),java,javafx,vbox,Java,Javafx,Vbox,如何在JavaFX中获取节点的高度或首选高度,我有3个VBox,我想将节点添加到最自由的面板中,例如: Childrens Total Height of the children's(Sum) VBoxA 5 890 VBoxB 4 610 VBoxC 2 720 在本例中,最自由的是VB

如何在JavaFX中获取节点的高度或首选高度,我有3个
VBox
,我想将节点添加到最自由的面板中,例如:

           Childrens      Total Height of the children's(Sum)
VBoxA          5                     890
VBoxB          4                     610
VBoxC          2                     720
在本例中,最自由的是
VBoxB
,我使用此方法计算最自由的窗格:

private int getFreerColumnIndex() {
    if(columns.isEmpty())
        return -1;

    int columnIndex = 0;
    int minHeight = 0;
    for(int i = 0; i < columns.size(); i++) {
        int height = 0;
        for(Node n : columns.get(i).getChildren()) {
            height += n.getBoundsInLocal().getHeight();
        }

        if(i == 0) {
            minHeight = height;
        } else if(height < minHeight) {
            minHeight = height;
            columnIndex = i;
        }

        if(height == 0)
            break;
    }

    return columnIndex;
}
将返回带有新节点的
0

有人知道如何获得节点的高度吗


额外:
SomeNode
扩展了
Node

myPane中的方法addElement():

public void addElement(final Node element) {
     index = getFreerColumnIndex();
     columns.get(index).getChildren().add(element);
}

额外2: 假设我们有3个vbox: 之前:

运行:

正确

 A      B      C
 |      |      |
 |      |      |
 |      |      |
 |      |      |
 |      |      |
 |
|
=某个节点

您需要做的是:

  • 创建要放置在VBox中的节点
  • 将它们添加到某个场景中(它可以只是一个新的虚拟场景,没有附加到舞台上,但具有与主场景相同的CSS规则)
  • 在每个节点(或虚拟场景根)上调用
    applyCss()
    layout()
  • 测量每个节点的布局边界
  • 根据布局算法将节点添加到真实场景中的VBox中 相关的

    要了解如何测量节点的大小,请参阅以下内容的答案:

    背景

    JavaFX布局计算通过应用CSS和布局过程来工作。通常情况下,这是脉冲的一部分(内部JavaFX系统中的一种自动60 fps滴答声,用于检查场景中需要应用新css或布局的任何脏对象)。在大多数情况下,您只需指定要对场景进行的更改,并让自动脉冲布局机制在此时处理布局;这样做非常有效,因为这意味着脉冲之间的任何更改都是成批进行的,您不需要手动触发布局过程。但是,当您需要在布局发生之前实际获取事物的大小时(如您的情况),那么您需要在尝试查询节点的高度和宽度范围之前手动触发CSS应用程序和布局过程

    文件

    不幸的是,该方法的详细Java8U20 Javadoc目前已被破坏,因此我将在这里复制Javadoc代码中的示例,以便您可以在上下文中看到推荐的用法。对于下一个Java特性版本(8u40),损坏的javadoc作为的一部分进行了修复,因此在该版本中,您将能够在JavaFX javadoc中找到以下文本:

    如果需要,将样式应用于此节点及其子节点(如果有)。此方法通常不需要 可以直接调用,但可以与
    layout()
    结合使用,以在 下一个脉冲,或者如果场景不在舞台上

    如果节点的场景不为空,CSS将应用于该节点 此节点的CSS状态是否干净。CSS样式从最顶端的父级应用 此节点的CSS状态不是clean,这可能会影响其他节点的样式。 如果节点不在场景中,则此方法为无操作。场景不一定要在舞台上

    此方法不调用
    layout()
    方法。通常,调用方将使用 遵循操作顺序

    parentNode.applyCss();
    parentNode.layout();
    
    作为更完整的示例,以下代码使用
    applyCss()
    layout()
    查找 显示舞台前按钮的宽度和高度。如果调用
    applyCss()
    或者对
    layout()
    的调用被注释掉,对
    getWidth()
    getHeight()的调用被注释掉
    将返回零(直到显示阶段后的一段时间)

    另类


    这里的另一个选项是重写父节点的方法,该方法“在布局过程中调用,以布局此父节点中的子节点”。在执行此操作时,可能还需要重写方法to以及prefWidth和min&max height&width的其他计算方法。使用这种方法的详细描述很复杂,超出了本答案的范围。

    对于新蜜蜂来说,这是一个非常全面的答案,这使得学习的本质更加容易
     A      B      C
     |      |      |
            |      |
            |
    
    for (int i = 0; i < 10; i++) {
        SomeNode r1 = new SomeNode ();
        myPane.addElement(r1);                      
    }
    
     A      B      C
     |      |      |
     |      |      |
     |      |
     |
     |
     |
     |
     |
     |
     |
     |
    
     A      B      C
     |      |      |
     |      |      |
     |      |      |
     |      |      |
     |      |      |
     |
    
    parentNode.applyCss();
    parentNode.layout();
    
    public void start(Stage stage) throws Exception {
       Group root = new Group();
       Scene scene = new Scene(root);
    
       Button button = new Button("Hello World");
       root.getChildren().add(button);
    
       root.applyCss();
       root.layout();
    
       double width = button.getWidth();
       double height = button.getHeight();
    
       System.out.println(width + ", " + height);
    
       stage.setScene(scene);
       stage.show();
    }