【问题标题】:Buttons in GridPane with prefWidth="Infinity" break JavaFXGridPane 中 prefWidth="Infinity" 的按钮会破坏 JavaFX
【发布时间】:2014-01-14 10:14:59
【问题描述】:

我刚开始使用 JavaFX,如果这是一个愚蠢的错误,请原谅。

我有一个GridPane,我想用它让两个相邻的按钮延伸到整个窗口的宽度。所以我创建了一个GridPane,其中包含一行和两个列,并添加到我的两个按钮中。

代码:

<GridPane id="GridPane" alignment="TOP_LEFT" disable="false" gridLinesVisible="false" hgap="5.0">
  <children>
     <Button mnemonicParsing="false"  styleClass="add-button" text="Save" GridPane.columnIndex="0" GridPane.rowIndex="0" />
     <Button mnemonicParsing="false"  text="Discard" GridPane.columnIndex="1" GridPane.rowIndex="0" />
  </children>
  <columnConstraints>
     <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
     <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
  </columnConstraints>
  <rowConstraints>
     <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
  </rowConstraints>
</GridPane>

但现在 Button 只占用了它们必要的空间。所以我给他们两个都加了prefWidth="Infinity"。这会导致 Secene Builder 1.1 立即冻结。我听说场景构建器曾经并且可能存在错误,因此我将其手动编码到 FXML 中并尝试运行该程序。程序启动但不打开窗口。

使用jvisualvm 检查正在运行的进程告诉我JavaFX 应用程序线程正在分配大量空间(数百万ArrayLists 会立即被垃圾收集)。它分配大约 1.2 GB/s。相反,当我尝试用它打开文件时,Scene Builder 似乎什么都不做,因为它使用的堆相当稳定,大约为 16MB(它也不会打开窗口)。

即使prefWidth 仅添加到一个Button 上,也会发生错误。例如,如果我在两个按钮上都使用prefWidth="100000000",我会得到想要的结果,但我觉得这是非常糟糕的编码。

所以我的问题是:

  • 这是 JavaFX 的错误吗?
  • 如何以更好的方式获得我想要的结果?

【问题讨论】:

    标签: javafx javafx-2 fxml


    【解决方案1】:

    您应该使用 maxWidth 而不是 prefWidth。 JavaFX 正在尝试将 MAX 值计算为按钮的初始大小,因为它是首选大小。最大尺寸只是一个参数,用于将实际尺寸与(在某些情况下,将尺寸设置为最小值(实际尺寸不够大:将其增加到最小尺寸)或最大值(实际尺寸太大) :将其缩小到最大尺寸)),这可能是您所需要的;具有“无限”值的 maxWidth / maxHeight 意味着您不会限制小部件的增长。

    默认情况下,最大尺寸等于 prefSize,这就是为什么你必须修改它以获得正确的 HGROW / VGROW。您在某些方面是正确的:您需要修改最大尺寸,但不要更改首选项尺寸。

    这样的事情应该可以工作:

    <Button fx:id="testButton"
            text="Test"
            maxWidth="Infinity"
            maxHeight="Infinity"
            GridPane.hgrow="ALWAYS"
            GridPane.vgrow="ALWAYS"
            GridPane.rowIndex="0"
            GridPane.columnIndex="0"/>
    

    【讨论】:

    • 确定设置maxWidth="Infinity" 确实解决了我的问题。但我不完全理解你的解释。我的看法是通过设置maxWidth="Infinity" 我告诉JavaFX“嘿,我的宽度基本上没有上限”,通过设置prefWidth="Infinity" 我说“嘿,我想在宽度上变得巨大(但这不是必需的) )”,以便 JavaFX 可以决定给我尽可能多的空间。但这以某种方式破坏了整个过程而没有错误消息或任何东西。
    • 如果maxWidth默认等于prefWidth,为什么它不起作用?
    • @mgttlinger prefSize 并不是一个“抽象”值,而是一个以像素为单位的显式值,如果可能的话,javafx 会将该值用于小部件。 ‘Infinity’只是表达成长的捷径,所以只能作为比较值。我认为 javafx 正在尝试使用 Integer.MAX_VALUE 绘制一个小部件作为首选项宽度,所以它只会杀死你的 JVM。
    猜你喜欢
    • 1970-01-01
    • 2017-02-11
    • 2022-01-19
    • 2012-05-16
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    相关资源
    最近更新 更多