gpt4 book ai didi

java - 获取JavaFX中节点的高度(生成布局 channel )

转载 作者:行者123 更新时间:2023-12-02 04:55:53 25 4
gpt4 key购买 nike

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

           Childrens      Total Height of the children's(Sum)
VBoxA 5 890
VBoxB 4 610
VBoxC 2 720

在这种情况下,最自由的是VBoxB,我用这个方法计算出最自由的 Pane :

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

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

<小时/>

额外:

SomeNode 扩展了 Node

myPane 的 addElement() 方法:

public void addElement(final Node element) {
index = getFreerColumnIndex();
columns.get(index).getChildren().add(element);
}
<小时/>

额外2:

假设我们有 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. 创建要放置在垂直框中的节点。
  2. 将它们添加到某个场景(它可以只是一个新的虚拟场景,未附加到舞台,但具有与主场景相同的 CSS 规则)。
  3. 在每个节点(或虚拟场景根)上调用 applyCss()layout()
  4. 测量每个节点的布局边界。
  5. 根据您的布局算法将节点添加到真实场景中的 VBox。

相关

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

背景

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

文档

不幸的是 node.applyCSS() 的详细 Java 8u20 Javadoc方法当前已损坏,因此我将在此处重现 Javadoc 代码中的示例,以便您可以在上下文中查看推荐的用法。对于下一个 Java 功能版本 (8u40),损坏的 javadoc 将作为 RT-38330 Javadoc is missing for several methods of the Node class 的一部分进行修复。 ,因此在该版本中,您将能够在 JavaFX javadoc 中找到以下文本:

If required, apply styles to this Node and its children, if any. This method does not normally need tobe invoked directly but may be used in conjunction with layout() to size a Node before thenext pulse, or if the Scene is not in a Stage.

Provided that the Node's Scene is not null, CSS is applied to this Node regardlessof whether this Node's CSS state is clean. CSS styles are applied from the topmost parentof this Node whose CSS state is other than clean, which may affect the styling of other nodes.This method is a no-op if the Node is not in a Scene. The Scene does not have to be in a Stage.

This method does not invoke the layout() method. Typically, the caller will use thefollowing sequence of operations.

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

As a more complete example, the following code uses applyCss() and layout() to findthe width and height of the Button before the Stage has been shown. If either the call to applyCss()or the call to layout() is commented out, the calls to getWidth() and getHeight()will return zero (until some time after the Stage is shown).

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

layout() 与 requestLayout()

调用layout()将立即执行布局传递。

调用 requestLayout() 将在将来执行布局传递:

Requests a layout pass to be performed before the next scene isrendered. This is batched up asynchronously to happen once per"pulse", or frame of animation.

因此 requestLayout() 通知系统需要进行布局,但不会立即进行布局。

通常情况下,你不需要直接调用requestLayout(),因为大多数时候,JavaFX系统能够在内部判断场景的某个区域是脏的,需要在需要时自动进行布局。

替代方案

这里的另一个选项是覆盖 layoutChildren()父节点的方法,“在布局过程中调用以布局此父节点中的子节点”。这样做时,可能还需要将方法重写为 computePrefHeight()以及 prefWidth 和最小和最大高度和宽度的其他计算方法。使用此方法的详细描述很复杂,超出了本答案的范围。

关于java - 获取JavaFX中节点的高度(生成布局 channel ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56411692/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com