JavaFX 中 `Scene` 的默认布局管理器是什么?

huangapple go评论92阅读模式
英文:

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控件也调整大小,以继续填充窗口。

JavaFX 中 `Scene` 的默认布局管理器是什么?

👁️‍🗨️ 在此示例中,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.

JavaFX 中 `Scene` 的默认布局管理器是什么?

👉🏼 What is the default layout manager of the Scene in this example?

答案1

得分: 7

在JavaFX中没有布局管理器。Scence API文档说明了Scene在调整大小时的行为:

如果使用Group作为根节点,场景图的内容将被场景的宽度和高度剪裁,场景的大小变化(如果用户调整舞台大小)不会改变场景图的布局。如果将可调整大小的节点(布局RegionControl)设置为根节点,那么根节点的大小将跟踪场景的大小,从而在必要时重新布局内容。

由于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(...)的实际实现是一个空操作,这也由ParentGroup继承。因此,如果根节点是Group的实例,实际上什么也不会发生。

另一方面,Region覆盖了resize(...)以将其宽度和高度设置为传入的值,从而导致根节点是Region实例的大小跟踪场景的大小。更改大小会触发在下一个渲染脉冲中调用layout()

layout()是一个final方法,首先调用layoutChildren()(它是可覆盖的,应该调整和定位子节点的大小),然后迭代调用任何子节点的layout(),这些子节点是Parent的实例。

因此,调整Scene大小并且其rootRegion实例的实际效果由该rootlayoutChildren()的实现确定。在Control(如TableView)的情况下,它被委托给skinSkin还定义了一个layoutChildren()方法,其实现确定了控件的各个组件在新的宽度和高度下的布局方式。

因此,在您的示例中,TableView的大小设置为控件的大小(由Regionresize()的实现确定),然后根据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.

huangapple
  • 本文由 发表于 2023年8月9日 15:02:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76865337-2.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定