嵌套ScrollPanes和FlowPanes / VBox的难度很高

时间:2015-03-18 15:28:28

标签: javafx javafx-8

Embedded containers with scrollbars

上面,我添加了一个屏幕截图 - 现在我可以添加图像了。屏幕截图的底部显示场景的边缘(外部容器2上没有滚动条)。

此场景可能会变得太忙 - 但我尝试使用包含FlowPane或VBox的嵌套滚动窗格。我正在定义“内部容器”,这是一个VBox,包括一个文本字段和滚动窗格,它有一个流动窗格作为它的内容。流窗格加载了许多“状态块”。内部容器的滚动窗格似乎正常工作。下面是内部容器的代码片段:

public class InnerContainer extends VBox
{
  // Declare the various parts of the inner container
  private TextField m_icName = null;     // Name of the inner container
  private ScrollPane m_icScroll = null; 

  private FlowPane m_icFlow = null;  // Holds the status blocks

  // List of status blocks in this inner container
  private ArrayList<StatusBlock> m_statBlockList = null;

  /******************************************************************
  *  Create the containers and controls used by the inner container *
  ******************************************************************/

  public InnerContainer()
  {
    m_statBlockList = new ArrayList<>();  // Set up list of status blocks  
    setMinSize(200.0, 170.0);      
    setPrefSize(200, 170);         
    setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    setPadding(new Insets(5, 5, 5, 5));

    m_icName = new TextField();
    m_icName.setMaxWidth(Double.MAX_VALUE);

    m_icScroll = new ScrollPane();
    m_icScroll.setFitToWidth(true);
    m_icScroll.setFitToHeight(true);
    m_icScroll.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    VBox.setVgrow(m_icScroll, Priority.ALWAYS);

    m_icFlow = new FlowPane();

    m_icFlow.setPrefWrapLength(650.0);  // This is the "wrap" point

    m_icFlow.setVgap(5);
    m_icFlow.setHgap(5);

    m_icFlow.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);

    m_icScroll.setContent(m_icFlow);

    // Add the elements to the vbox
    getChildren().addAll(m_icName, m_icScroll);   

    VBox.setVgrow(this, Priority.ALWAYS);

我无法让滚动条适用于外部容器。如果我添加内部容器,外部容器会不断增长,我永远无法显示滚动条(即使它超出了屏幕的大小)。我怀疑我无法正确计算外部容器内容的大小。外部容器是VBox,其包含文本字段和具有VBox内容的滚动窗格。最终的VBox可以由一个到多个内部容器组成。

以下是外部容器的代码段:

public class OuterContainer extends VBox
{

  // Declare the various parts of the outer container
  private TextField m_ocName = null;     // Name of the outer container
  private ScrollPane m_ocScroll = null;
  private VBox m_ocMainVBox = null;
  private ArrayList<InnerContainer> m_innerContList = null;

  public OuterContainer()
  {
    // Setup the inner container list
    m_innerContList = new ArrayList<>();

    setSpacing(8);
    setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);      
    setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    setPadding(new Insets(5, 5, 5, 5));

    m_ocName = new TextField();
    m_ocName.setMaxWidth(Double.MAX_VALUE);

    m_ocScroll = new ScrollPane();
    m_ocScroll.setFitToWidth(true);
    m_ocScroll.setFitToHeight(true);
    m_ocScroll.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    VBox.setVgrow(m_ocScroll, Priority.ALWAYS);   

    m_ocMainVBox = new VBox();
    m_ocMainVBox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    VBox.setVgrow(m_ocMainVBox, Priority.ALWAYS);   
    m_ocMainVBox.setSpacing(5);
    m_ocMainVBox.setMinSize(1.0, 1.0);

    m_ocScroll.setContent(m_ocMainVBox);

    // Add the elements to the top vbox
    getChildren().addAll(m_ocName, m_ocScroll);

    VBox.setVgrow(this, Priority.ALWAYS);

最后一个外部类也应该有一个滚动条。它也无法正常工作,但我怀疑这个问题类似于我在这里寻求帮助的问题。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我放弃了尝试使用三个滚动条,而是使用一个滚动条。但是,我认为根本问题已经解决了:

Java FX scales the parent based on the content size

随着内容大小的增长,用作ScrollPane内容的FlowPane或VBox的大小也在不断增长。这也导致滚动板的高度增加。为了解决这个问题,我现在将滚动窗格的pref高度基于舞台的高度。我还添加了一个更改侦听器,用于查找舞台高度属性的更改。它类似于以下代码段:

m_dashScroll.setPrefHeight(TopClass.getStage().getHeight() - DECORATION_OFFSET);

TopClass.getStage().heightProperty().addListener(new ChangeListener<Number>()
{
  @Override
  public void changed(ObservableValue<? extends Number> ov,
                      Number oldVal, Number newVal)
  {
    m_dashScroll.setPrefHeight(newVal.doubleValue() - DECORATION_OFFSET);
  }
});

这需要对舞台的静态引用,所以如果有更好的方法,我会感兴趣。 [另外,如果需要,我可以在这里使用lambda。]