当前位置: 首页 > 知识库问答 >
问题:

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

袁旻
2023-03-14

如何在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;
}

此方法仅在我同时添加1个元素时有效。但如果我当时添加更多元素:

for (int i = 0; i < 10; i++) {
    SomeNode r1 = new SomeNode ();
    myPane.addElement(r1);
}

方法getFreerColumnIndex返回相同的索引。这是因为新节点在本地还没有高度。
因此这行:

height += n.getBoundsInLocal().getHeight(); 

将返回带有新节点的0

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

Node的扩展

方法addElement()在myPane:

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

假设我们有3个vbox:之前:

 A      B      C
 |      |      |
        |      |
        |

运行:

for (int i = 0; i < 10; i++) {
    SomeNode r1 = new SomeNode ();
    myPane.addElement(r1);                      
}

之后:

 A      B      C
 |      |      |
 |      |      |
 |      |
 |
 |
 |
 |
 |
 |
 |
 |

对的:

 A      B      C
 |      |      |
 |      |      |
 |      |      |
 |      |      |
 |      |      |
 |

|=某个节点

共有1个答案

常元章
2023-03-14

您需要做的是:

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

相关的

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

  • 如何在JavaFX中计算字符串的像素宽度?

背景资料

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

文档

不幸的是,用于node.applyCSS()方法的详细Java8u20 Javadoc当前已被破坏,因此我将在此处重现Javadoc代码中的示例,以便您可以在上下文中查看推荐的用法。对于下一个Java功能版本(8u40),损坏的javadoc是固定的,因为RT-38330的一部分节点类的几个方法缺少Javadoc,所以有了这个版本,你将能够在JavaFX javadoc中找到以下文本:

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

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

此方法不调用布局()方法。通常,调用者将使用以下操作序列。

parentNode.applyCss();
parentNode.layout();

作为一个更完整的示例,下面的代码使用appyCss()布局()来查找显示舞台之前Button的宽度和高度。如果对appyCss()的调用或对布局()的调用被注释掉,对getWidth()getHeight()的调用将返回零(直到阶段显示后的一段时间)...

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();
}

备选方案

这里的另一个选项是覆盖父节点的layoutChildren()方法,该方法“在布局过程中调用,以布局此父节点中的子节点。”。在执行此操作时,可能还需要重写computePrefHeight()的方法以及prefWidth和min的其他计算方法

 类似资料:
  • 问题内容: 如何在JavaFX中获取节点的高度或首选节点的高度,我有3个节点,我想将节点添加到最自由的面板中,例如: 在这种情况下,最自由的是,我使用这种方法计算出最自由的窗格: 仅当我一次添加1个元素时,此方法才有效。但是如果我一次添加更多元素: 该方法getFreerColumnIndex返回相同的索引。这是因为新节点在本地还没有高度。 所以这行: 将0与新节点一起返回。 有谁知道如何获得节点

  • 问题内容: 如何在JavaFX中获取节点的高度或首选节点的高度,我有3个节点VBox,我想将节点添加到最自由的面板中,例如: 在这种情况下,最免费的是VBoxB,我使用这种方法计算出最免费的窗格: 仅当我一次添加1个元素时,此方法才有效。但是如果我一次添加更多元素: 该方法getFreerColumnIndex返回相同的索引。这是因为新节点在本地还没有高度。 所以这行: 将0与新节点一起返回。 有

  • 我刚刚开始学习JavaFX来构建桌面应用程序,目前还没有任何个人培训。现在关于这个问题,我正在尝试做一个自定义布局,它的大小取决于它的孩子的整体大小。我的问题是在计算高度和宽度时得到每个孩子的尺寸。这里,我使用< code>getLayoutBounds()方法来检索孩子的尺寸,但是在我的例子中,它总是返回0: 所以我想这是关于布局传递的(比如说,孩子还没有布局)。但是不管怎样,如果这里是不是这样

  • 我正在开发一个应用程序,有必要将节点布置在彼此之外(或彼此顶部等)。但是,此布局只是初始布局,用户可以任意移动这些节点。在JavaFX中,如何以正确的方式实现这一点?我将用一个简单的例子来解释我的问题: 假设我有两个矩形,想把矩形2放在矩形1的右边。 在这种情况下,JavaFX还没有确定rect1的宽度,它将为零。直观地说,我会执行一个调用,让JavaFX绘制rect1,从而确定其宽度,然后添加r

  • 问题内容: 在JavaFX中获取节点绝对位置的最佳方法是什么? 假设我们在窗格(Hbox,Stackpane或任何其他窗格)中有一个节点,并且它本身可能有一个父节点。 我想获取该节点的绝对位置,并在另一个窗格中使用它。 问题答案: 这取决于您所说的“绝对”的含义。节点有一个坐标系,父节点有一个坐标系,父节点有一个坐标系,依此类推,最终有一个坐标系和一个屏幕坐标系(可能是物理显示设备的集合)。 您可

  • 我正在编写一个javafx UI,希望从单击的MenuItem的eventHandler中获取contextMenu的所有者节点。 我的代码: 我想做的是获取一个对选中了上下文菜单的选项卡的引用。 我能够通过MenuItem eventHandler的handle(ActionEvent e)方法中的以下代码获得对MenuItem ContextMenu的引用: 我的想法是在菜单上使用Contex