2017-05-31 44 views
2

我想创建一组使用JavaFX 8的自定义控件。我有点困惑什么是正确的方式来做一些东西,如布置我定义的孩子建立我的控制。 我用来重写layoutChildren()方法,在这里我重新定位并调整了孩子的大小;但阅读javadoc的layoutChildren()有写:JavaFX 8 - 自定义控件和他们的孩子

在布局过程中调用布局在此父级中的子级。默认情况下,它只会将受管理的可调整大小的内容设置为其首选大小,并且不会执行任何节点定位。

因此,根据文档,我不得执行子节点的任何重定位(“节点定位”)。

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

我不明白的另一件事是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()被调用每帧

+0

因此,你建议我在重写方法,我可以做节点定位?这似乎违反了超级合同。 – Vin

+0

“默认情况下,x确实......”不是合同。在这种特殊情况下,Javadocs明确告诉你,如果需要的话,子类应该定位节点:“子类应该覆盖此函数以根据需要布置内容。” –

+0

我们可以有一个自定义布局管理器如何工作的想法或形象吗?编写类似代码的可能性很高,因此我们可以提供帮助。 – GOXR3PLUS

回答

3

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

子类应该重写此函数以根据需要布局内容。

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

我不明白何时执行“布局传递”。

package documentation for javafx.scene.layout

场景图形布局机构由系统一旦应用程序创建和显示一个Scene自动驱动。场景图检测到影响布局的动态节点变化(例如大小或内容的变化),并调用requestLayout(),该变量将分支标记为需要布局,以便在下一个脉冲时,在该分支上执行自顶向下的布局传递在该分支的根上调用layout()。在布局过程中,layoutChildren()回调方法将在每个父级上调用以布局其子级。该机制旨在通过确保多个布局请求合并并一次处理,而不是在每分钟更改时执行重新布局,从而最大限度地提高布局效率。因此,应用程序不应直接在节点上调用布局。

所以父节点将“自动”(*)标记本身为需要布局如果任何其子项的大小或内容节点的变化。在每个渲染脉冲上,如果父级需要布局,则将调用layoutChildren()方法。这意味着你所要做的就是实现layoutChildren()方法,它将在需要时为你调用。 (*)虽然我没有真正看到源代码,但是我对这种工作原理的理解是,父代绑定到其子节点的布局边界:如果任何子节点的边界失效,然后它在下一个渲染脉冲上重新计算其布局。反过来,如果内容改变(例如,如果文本改变,标签将使其布局边界失效等),则节点将使其自己的布局边界失效。换句话说,JavaFX observable properties and bindings驱动布局机制。

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

+0

有用的答案,谢谢。但是我注意到,在某些情况下,如果我将println()放入方法中,则会在每个帧上调用该方法。我认为这不是一种正确的行为,因为看起来布置孩子会导致幕后调整控制布局,等等......我不知道你是否理解我的意思。 – Vin

+0

@Vin我需要看到发生的一个例子。 –

+0

这是diffucult显示,因为它是很多的代码,我会尝试以更简单的代码重现此行为。 – Vin

相关问题