解
将ListView封装在非托管容器中。任何容器都可以,例如Group或任何Pane或Pane子类。不要将ListView本身设置为非托管。
背景
在这方面不受管理的,意味着容器节点上setManaged(false)的显式调用。这意味着节点的自动布局被禁用,并且用户应用程序代码必须明确地管理布局属性(例如节点大小和宽度以及请求非托管节点的子节点的自动布局)。所以矛盾的是你的应用程序代码必须明确地管理容器布局。
如果您将ListView本身设为非托管,我的猜测(这只是一个猜测)是,这打破了ListView的内部布局算法,并防止ListView被正确显示,因为ListView中的组件可能期待ListView本身被管理。
当您将ListView放入另一个未托管的容器中时,那么ListView本身仍在内部管理,因此其布局不会中断,但布局与场景的常规布局不相交,非托管容器变为根用于ListView的布局。通过这种方式,您可以手动设置非托管容器(及其子项)的位置和首选大小,从而有效实现为ListView提供应用程序托管布局的目标。
实用性
我注意到像的TextField其他控件相同的行为,所以这可能是可以用于任何控制的非托管显示器的一般模式。
另请注意,此请求有些不寻常。对于大多数应用程序,不需要非托管控件。内置的布局管理器可以处理各种各样的布局需求。当需要自定义布局时,该方法是创建自定义布局管理器(例如新窗格子类)并覆盖layoutChildren()和computePrefHeight/computePrefWidth/computeMinHeight/computeMinWidth方法。这允许您的应用程序或组件以自动的方式与自动JavaFX布局系统进行交互。有关这种功能样式的示例,请查看内置布局管理器的代码,例如StackPane。
样品
下面是一个示例应用程序来演示这些原则和实现你的问题ListView中规定的尺寸和位置的目标。我将屏幕截图大小缩小为一半,所以不占用太多空间。这些测量结果对我来说有点欺骗性,它看起来并不像列表放置在100,200尺寸为300,400的尺寸,但是我在图形应用程序中测量它,并且按照预期放置和调整尺寸。
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]
但首先,你为什么要设置列表视图不管理? –
这是自定义组件的一部分,我不希望ListView占用空间。它显示为一种覆盖作为自动完成输入。我知道这可以通过其他方式实现。不过,我想了解为什么我无法实现这个功能,我想更好地理解JavaFX。 – T3rm1