2015-10-14 22 views
2

比方说,我有以下布局:将分量可见管理的时候是假

<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
顶= 200
宽度= 300
高度= 400

+1

但首先,你为什么要设置列表视图不管理? –

+0

这是自定义组件的一部分,我不希望ListView占用空间。它显示为一种覆盖作为自动完成输入。我知道这可以通过其他方式实现。不过,我想了解为什么我无法实现这个功能,我想更好地理解JavaFX。 – T3rm1

回答

1

将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的尺寸,但是我在图形应用程序中测量它,并且按照预期放置和调整尺寸。

unmanaged

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] 
+0

非常感谢您的努力。我可以按照你的猜测,我认为这是可信的。 – T3rm1

相关问题