Listview 当managed为false时使组件可见

Listview 当managed为false时使组件可见,listview,javafx,Listview,Javafx,假设我有以下布局: <VBox xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1"> <children> <TextField fx:id="textField" /> <ListView fx:id="list" visible="true" /> </children> </VBox>

假设我有以下布局:

<VBox xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <TextField fx:id="textField" />
      <ListView fx:id="list" visible="true" />
   </children>
</VBox>

只要我调用
listView.setManaged(false)
无论我设置了哪些布局属性,listView都是不可见的。也许我错过了一些

要查看具有这些示例值的ListView,我必须设置哪些属性:
左=100
Top=200
宽度=300
高度=400

将ListView包装在非托管容器中。任何容器都可以,例如,a或任何窗格或子类。不要将ListView本身设置为非托管

背景

在此上下文中为非托管,表示在容器节点上显式调用。这意味着禁用节点的自动布局,用户应用程序代码必须显式管理布局属性(例如节点大小和宽度,以及请求非托管节点子节点的自动布局)。因此,矛盾的是,应用程序代码必须显式管理容器布局

如果将ListView本身设置为非托管,我猜测(这只是猜测)这会破坏ListView的内部布局算法,并阻止ListView正确显示,因为ListView中的组件可能希望管理ListView本身

如果将ListView放置在另一个非托管容器中,则ListView本身仍处于托管状态,因此其内部布局不会中断,但布局与场景的常规布局不相交,且非托管容器成为ListView布局的根。这样,您就可以手动设置非托管容器(及其子容器)的位置和首选大小,从而有效地实现ListView的应用程序托管布局的目标

适用性

我注意到了其他控件(如TextField)的相同行为,因此这可能是一种通用模式,可用于任何控件的非托管显示

还要注意,这个请求有些不寻常。对于大多数应用程序,不需要非托管控件。内置布局管理器可以处理各种各样的布局需求。当需要自定义布局时,该方法是创建自定义布局管理器(例如,新的窗格子类)并重写和computePrefHeight/computePrefWidth/ComputeMinHight/computeMinWidth方法。这允许应用程序或组件以友好的方式与自动JavaFX布局系统交互。有关此类功能样式的示例,请查看内置布局管理器的代码,例如

样品

下面是一个示例应用程序,用于演示这些原则,并实现问题中为ListView规定的大小调整和放置目标。我将屏幕截图的大小调整为一半,这样就不会占用太多空间。测量结果有点欺骗性,因为在视觉上,我看不出列表的位置是100200,大小是300400,但我在图形应用程序中测量了它,它的位置和大小与预期一致


但首先,为什么要将listview设置为非托管?这是自定义组件的一部分,我不希望listview占用空间。它显示为一种覆盖,用作自动完成输入。我知道这可以通过其他方式实现。不过我还是想理解为什么我不能让它工作,我想更好地理解JavaFX。非常感谢你的努力。我能理解你的猜测,我认为这是合理的。
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Unmanageable extends Application {
    @Override
    public void start(final Stage stage) throws Exception {
        TextField textField = new TextField();

        ListView<String> listView = new ListView<>();
        listView.getItems().addAll("Sally", "Sells", "Seashells", "At", "The", "Seashore");
        listView.setStyle("-fx-base: lightcoral;");

        Group unmanagedContainer = new Group(listView);
        unmanagedContainer.setManaged(false);
        unmanagedContainer.relocate(100, 200);

        listView.setMinSize(ListView.USE_PREF_SIZE, ListView.USE_PREF_SIZE);
        listView.setPrefSize(300, 400);
        listView.setMaxSize(ListView.USE_PREF_SIZE, ListView.USE_PREF_SIZE);

        VBox layout = new VBox(textField, unmanagedContainer);
        layout.setMinSize(600, 800);
        layout.setStyle("-fx-background-color: azure;");

        stage.setScene(new Scene(layout));
        stage.show();

        System.out.println(unmanagedContainer.getBoundsInParent());
    }

    public static void main(String[] args) throws Exception {
        launch(args);
    }
}
BoundingBox [minX:100.0, minY:200.0, minZ:0.0, width:300.0, height:400.0, depth:0.0, maxX:400.0, maxY:600.0, maxZ:0.0]