Module  javafx.graphics

Package javafx.scene.layout

提供类来支持用户界面布局。 每个布局窗格类都支持其子项的不同布局策略,应用程序可以嵌套这些布局窗格,以在用户界面中实现所需的布局结构。 一旦将节点添加到其中一个布局窗格中,窗格将自动管理节点的布局,因此应用程序不应直接放置或调整节点大小; 有关详细信息,请参阅“节点可重定向”。

场景图布局机制

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

节点可重定向

场景图支持可调节大小和不可调整大小的节点类。 isResizable()上方法Node返回是否一个给定的节点是可调整大小或没有。 可调整大小的节点类是支持可接受大小(最小<= preferred <= maximum)范围的类,允许其父级在布局期间将其调整到该范围内,给定父级自己的布局策略和兄弟节点的布局需求。 Node支持以下布局代码方法来确定节点的可调整大小范围:

   public Orientation getContentBias() public double minWidth(double height) public double minHeight(double width) public double prefWidth(double height) public double prefHeight(double width) public double maxWidth(double height) public double maxHeight(double width)  

另一方面, 不可调整大小的节点类没有一致的调整大小的API,因此在布局期间,父节点不会调整其大小。 应用程序必须通过在每个实例上设置适当的属性来建立不可调整节点的大小。 这些类返回当前的min,pref和max的布局边界,而resize()方法成为无操作。


可调整大小的类: RegionControlWebView
不可调整大小类: GroupShapeText

例如,一个Button控件(可调整大小的)计算其最小,最小和最大大小,其父级将在布局期间使用它来调整其大小,因此应用程序只需要配置其内容和属性:

   Button button = new Button("Apply");  
然而,Circle(不可调整大小)不能由其父级调整大小,因此应用程序需要设置适当的几何属性来确定其大小:
   Circle circle = new Circle(); circle.setRadius(50);  

可调整范围

每个可调整大小的节点类根据自己的内容和属性设置(它是“内在”大小范围)来计算适当的最小,最小和最大大小。 一些可调整大小的类具有无限大的最大大小(所有布局窗格),而另一些具有最大大小,默认被锁定到其首选大小(按钮)(有关每个类的默认范围,请参阅各个类文档)。 虽然这些默认值适用于常见用法,但应用程序通常需要显式更改或设置节点的可调整大小范围才能实现某些布局。 可调整大小的类提供用于覆盖最小,最小和最大大小的属性。

例如,要覆盖ListView的首选大小:

   listview.setPrefSize(200,300);  

或者,要更改按钮的最大宽度,因此它将会更大的宽度来填充空格:

   button.setMaxWidth(Double.MAX_VALUE);  

对于逆情况,应用程序需要将节点的最小或最大大小钳制为首选:

   listview.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);  
最后,如果应用程序需要恢复本机计算的值:
   listview.setPrefSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);  

CSS样式和节点大小

应用程序无法可靠地查询可调整大小的节点的边界,直到它被添加到场景中,因为该节点的大小可能取决于CSS。 这是因为CSS用于创建一个影响其优先大小(字体,填充,边框等)的节点的许多方面,因此节点不能被布局(调整大小),直到应用CSS并且父级可以访问有效大小范围指标。 这对于控件(以及包含它们的所有窗格)始终是正确的,因为它们依赖CSS作为其默认样式,即使没有设置用户级样式表。 样式表设置在场景级别,这意味着在节点的包围场景已初始化之前,甚至无法确定样式。 一旦场景被初始化,CSS将在布局通过之前应用于每个脉冲上的节点(需要时)。

视觉界限与布局界限

图形丰富的用户界面通常需要区分节点的视觉边界和用于布局的边界。 例如,文本节点的字符字形的紧密的视觉边界对于布局将不起作用,因为文本将不会对齐,并且引导/尾随空格将被打折。 此外,有时应用程序希望应用影响和转换到节点,而不会影响周围的布局(弹跳,抖动,阴影,发光等)。 为了支持这种区别在场景图中, Node提供layoutBounds属性来定义节点的“逻辑”边界布局和boundsInParent定义可视边界,一旦所有的效果,夹持,和转换已经被应用。

对于给定的节点,这两个边界的属性通常会有所不同, layoutBounds根据节点类别的不同而不同:

Bounds Computation Table Node Type Layout Bounds Shape,ImageView Includes geometric bounds (geometry plus stroke). Does NOT include effect, clip, or any transforms. Text logical bounds based on the font height and content width, including white space. can be configured to be tight bounds around chars glyphs by setting boundsType. Does NOT include effect, clip, or any transforms. Region, Control, WebView always [0,0 width x height] regardless of visual bounds, which might be larger or smaller than layout bounds. Group Union of all visible childrens' visual bounds (boundsInParent) Does NOT include effect, clip, or transforms set directly on group, however DOES include effect, clip, transforms set on individual children since those are included in the child's boundsInParent.

所以例如,如果一个DropShadow被添加到一个形状,默认情况下,这个阴影不会被考虑到布局中。 或者,如果使用ScaleTransition来脉冲按钮的大小,则该脉冲动画不会打扰该按钮周围的布局。 如果应用程序希望将效果,剪辑或变换考虑到节点的布局中,则应将该节点包装在组中。