英文:
What is the default layout manager for a `Scene` in JavaFX?
问题
以下是您要翻译的内容:
这是我在JavaFX/OpenJFX的TableView
Javadoc中展示的示例代码的版本。 (Person
类是一个record,只读的。)
package work.basil.example.jfxexample;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import java.util.List;
public class HelloApplication extends Application
{
@Override
public void start ( Stage stage )
{
TableView < Person > tableViewPersons = new TableView <> ( );
ObservableList < Person > persons = FXCollections.observableArrayList ( this.fetchPersons ( ) );
tableViewPersons.setItems ( persons );
TableColumn < Person, String > firstNameCol = new TableColumn <> ( "First Name" );
firstNameCol.setCellValueFactory ( ( TableColumn.CellDataFeatures < Person, String > p ) -> new SimpleStringProperty (p.getValue().getFirstName ()));
TableColumn < Person, String > lastNameCol = new TableColumn <> ( "Last Name" );
lastNameCol.setCellValueFactory ( ( TableColumn.CellDataFeatures < Person, String > p ) -> new SimpleStringProperty (p.getValue().getLastName ()));
List < TableColumn < Person, ? > > columns = List.of ( firstNameCol , lastNameCol ); // <--- Adding this line to make explicit the parameterized type of `TableColumn` to resolve the "Unchecked generics" warning.
tableViewPersons.getColumns ( ).setAll ( columns );
Scene scene = new Scene ( tableViewPersons , 320 , 240 );
stage.setTitle ( "JavaFX Example" );
stage.setScene ( scene );
stage.show ( );
}
private List < Person > fetchPersons ( )
{
return List.of (
new Person ( "William" , "Reed" ) ,
new Person ( "James" , "Michaelson" ) ,
new Person ( "Julius" , "Dean" ) );
}
public static void main ( String[] args )
{
launch ( );
}
}
这个应用程序展示了一个充满表格视图的窗口。调整窗口大小会导致TableView
控件也调整大小,以继续填充窗口。
👁️🗨️ 在此示例中,Scene
的默认布局管理器是什么?
英文:
Here is my version of the example code shown in the Javadoc for TableView
in JavaFX/OpenJFX. (The Person
class is a record, read-only.)
package work.basil.example.jfxexample;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import java.util.List;
public class HelloApplication extends Application
{
@Override
public void start ( Stage stage )
{
TableView < Person > tableViewPersons = new TableView <> ( );
ObservableList < Person > persons = FXCollections.observableArrayList ( this.fetchPersons ( ) );
tableViewPersons.setItems ( persons );
TableColumn < Person, String > firstNameCol = new TableColumn <> ( "First Name" );
firstNameCol.setCellValueFactory ( ( TableColumn.CellDataFeatures < Person, String > p ) -> new SimpleStringProperty (p.getValue().getFirstName ()));
TableColumn < Person, String > lastNameCol = new TableColumn <> ( "Last Name" );
lastNameCol.setCellValueFactory ( ( TableColumn.CellDataFeatures < Person, String > p ) -> new SimpleStringProperty (p.getValue().getLastName ()));
List < TableColumn < Person, ? > > columns = List.of ( firstNameCol , lastNameCol ); // <--- Adding this line to make explicit the parameterized type of `TableColumn` to resolve the "Unchecked generics" warning.
tableViewPersons.getColumns ( ).setAll ( columns );
Scene scene = new Scene ( tableViewPersons , 320 , 240 );
stage.setTitle ( "JavaFX Example" );
stage.setScene ( scene );
stage.show ( );
}
private List < Person > fetchPersons ( )
{
return List.of (
new Person ( "William" , "Reed" ) ,
new Person ( "James" , "Michaelson" ) ,
new Person ( "Julius" , "Dean" ) );
}
public static void main ( String[] args )
{
launch ( );
}
}
This app presents a window filled with the table view. Resizing the window results in the TableView
control being resized as well, to continue filling the window.
👉🏼 What is the default layout manager of the Scene
in this example?
答案1
得分: 7
在JavaFX中没有布局管理器。Scence API文档说明了Scene
在调整大小时的行为:
如果使用
Group
作为根节点,场景图的内容将被场景的宽度和高度剪裁,场景的大小变化(如果用户调整舞台大小)不会改变场景图的布局。如果将可调整大小的节点(布局Region
或Control
)设置为根节点,那么根节点的大小将跟踪场景的大小,从而在必要时重新布局内容。
由于TableView
是一个Control
,所以后一种行为是你所看到的行为。
英文:
There are no layout managers in JavaFX.
The Scence API documentation states how Scene
behaves on resizing:
> If a Group is used as the root, the contents of the scene graph will be clipped by the scene's width and height and changes to the scene's size (if user resizes the stage) will not alter the layout of the scene graph. If a resizable node (layout Region or Control) is set as the root, then the root's size will track the scene's size, causing the contents to be relayed out as necessary.
Since TableView
is a Control
, the latter behavior is what you get and what you see.
答案2
得分: 4
在另一个答案中指出,JavaFX没有显式的布局管理器(与AWT以及因此而来的Swing不同),当调整Scene
的大小(例如,当用户调整包含它的窗口的大小)时,其行为在API文档中有描述。
将问题
这个示例中的
Scene
的默认布局管理器是什么?
更一般地理解为“Scene
默认情况下如何执行布局”,实际上发生的情况是,当场景改变大小时,它会在根节点上调用resize(...)
,传入其新的宽度和高度。
(请注意,虽然这是“默认”的行为,但这也是唯一的行为:它无法更改。)
在Node
中定义的resize(...)
的实际实现是一个空操作,这也由Parent
和Group
继承。因此,如果根节点是Group
的实例,实际上什么也不会发生。
另一方面,Region
覆盖了resize(...)
以将其宽度和高度设置为传入的值,从而导致根节点是Region
实例的大小跟踪场景的大小。更改大小会触发在下一个渲染脉冲中调用layout()
。
layout()
是一个final
方法,首先调用layoutChildren()
(它是可覆盖的,应该调整和定位子节点的大小),然后迭代调用任何子节点的layout()
,这些子节点是Parent
的实例。
因此,调整Scene
大小并且其root
是Region
实例的实际效果由该root
的layoutChildren()
的实现确定。在Control
(如TableView
)的情况下,它被委托给skin。Skin
还定义了一个layoutChildren()
方法,其实现确定了控件的各个组件在新的宽度和高度下的布局方式。
因此,在您的示例中,TableView
的大小设置为控件的大小(由Region
中resize()
的实现确定),然后根据TableViewSkin
的实现对表视图进行布局。
英文:
As pointed out in another answer, JavaFX does not have explicit layout managers (as AWT, and consequently Swing, does), and the behavior when resizing a Scene
(for example, when the user resizes the window containing it) is described in the API documentation.
Taking the question
> What is the default layout manager of the Scene
in this example?
to more generally mean "how does a Scene
perform layout by default", what actually happens when a scene changes size is that it invokes resize(...)
on the root node, passing in its new width and height.
(Note that while this is the "default" behavior, it is also the only behavior: it cannot be changed.)
The actual implementation of resize(...)
defined in Node
is a no-op, and this is inherited by both Parent
and Group
. So if the root node is an instance of Group
, nothing actually happens.
Region
, on the other hand, overrides resize(...)
to set its width and height to the values passed in, thereby causing the size of a root that is an instance of Region
to track the size of the scene. Changing the size triggers a call to layout()
on the next rendering pulse.
layout()
, which is a final
method, is defined to first call layoutChildren()
(which is overridable and should resize and position the child nodes), and then iteratively call layout()
on any child nodes which are instances of Parent
.
So the actual effect of resizing the Scene
whose root
is an instance of Region
is determined by the implementation of layoutChildren()
for that root
. In the case of a Control
, such as TableView
, it is delegated to the skin. Skin
additionally defines a layoutChildren()
method whose implementation determines how the various components of the control are laid out in the new width and height.
Consequently in your example, the size of the TableView
is set to the size of the control (by the implementation of resize()
in Region
), and the table view is then laid out according to the implementation of TableViewSkin
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论