gpt4 book ai didi

JavaFX 8 - 自定义控件及其子控件

转载 作者:行者123 更新时间:2023-12-01 13:34:55 26 4
gpt4 key购买 nike

我正在尝试使用 JavaFX 8 创建一组自定义控件。我对做一些事情的正确方法有点困惑,比如布置我定义的子项来构建我的控件。我用来重写 layoutChildren() 方法,在那里我重新定位和调整 child 的大小;但是阅读 layoutChildren() 的 javadoc 是这样写的:

Invoked during the layout pass to layout the children in this Parent. By default it will only set the size of managed, resizable content to their preferred sizes and does not do any node positioning.

因此,根据文档,我不能对 child 执行任何重定位(“节点定位”)。

我想了解的是在我的自定义控件中定位和调整子项大小的正确方法是什么。

我不明白的另一件事是调用 layoutChildren() 的时间和次数;文档说“在布局过程中调用”,但我不明白何时执行“布局过程”。

我希望你能帮助我。


编辑@James_D

这是我在评论里说的例子

public class MyControl extends TextField {
private Label label;

public MyControl() {
super();
setSkin(new TextFieldSkin(this));

label=new Label("This is my custom textfield");
getChildren().add(label);
}

@Override
protected void layoutChildren() {
super.layoutChildren();
label.relocate(0, -label.getHeight());

System.out.println("I'm laying out children");
}
}

如果你运行它,你会注意到每帧都会调用 layoutChildren()

最佳答案

您误解了 Javadocs you quoted ,它描述了 Parent.layoutChildren() 的作用。它并不是说子类不能定位节点;事实上,下一句话是

Subclasses should override this function to layout content as needed.

所以这正是您应该重写以布局子节点的方法。

I don't understand when "layout pass" is performed.

来自package documentation for javafx.scene.layout :

The scene graph layout mechanism is driven automatically by the system once the application creates and displays a Scene. The scene graph detects dynamic node changes which affect layout (such as a change in size or content) and calls requestLayout(), which marks that branch as needing layout so that on the next pulse, a top-down layout pass is executed on that branch by invoking layout() on that branch's root. During that layout pass, the layoutChildren() callback method will be called on each parent to layout its children. This mechanism is designed to maximize layout efficiency by ensuring multiple layout requests are coalesced and processed in a single pass rather than executing re-layout on on each minute change. Therefore, applications should not invoke layout directly on nodes.

因此,如果其任何子节点的大小或内容发生变化,父节点将“自动”(*) 将自身标记为需要布局。在每个渲染脉冲中,如果父级需要布局,将调用其 layoutChildren() 方法。这意味着您所要做的就是实现 layoutChildren() 方法,它会在需要时为您调用。

(*) 虽然我没有真正查看源代码,但我对其工作原理的理解是父节点绑定(bind)到其子节点的布局边界:如果任何子节点的边界无效,则它会在下一个渲染脉冲时重新计算其布局。反过来,如果内容发生变化,节点将使其自己的布局边界失效(例如,如果文本发生变化,标签将使其布局边界失效等)。换句话说,JavaFX observable properties and bindings驱动布局机制。

So (TL;DR): Parent(或Region,甚至)子类的layoutChildren()方法 Pane ,取决于您需要的功能)正是调整子节点大小和重新定位子节点的正确位置。如果(且仅当)父级需要重新计算其布局,则每次渲染场景时都会调用该方法。

关于JavaFX 8 - 自定义控件及其子控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44281794/

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