JavaFX:GridPane 中的 ComboBox 导致不必要的大小调整

Posted

技术标签:

【中文标题】JavaFX:GridPane 中的 ComboBox 导致不必要的大小调整【英文标题】:JavaFX: ComboBox in GridPane causes unnecessary resizing 【发布时间】:2017-10-09 20:04:45 【问题描述】:

我有一个有 5 列的 GridPane。这些分别是我为列约束设置的hgrow

    SOMETIMES ALWAYS SOMETIMES(固定大小) SOMETIMES ALWAYS

整个GridPane 基本上是一个两列表单的布局。我的第 1 列和第 4 列(索引 0 和 3)是字段标签,而第 2 列和第 5 列是输入字段(TextField 等)。第 3 列只是两个表单列之间的固定宽度填充。

我的表单中有一些ComboBox - 有些在左列,有些在右列。我已将所有ComboBox 的最大宽度设置为MAX_VALUE

当表单加载时,布局看起来就像我想要的那样(两个输入字段列的宽度相等)。但是,当我点击任何ComboBox 时,它会导致点击ComboBox 所在的列的宽度增加 - 这会导致其他输入字段列减少相同的数量。

我可以交替点击左侧和右侧的ComboBox,两列的宽度会不断变化。变化会越来越小,最终列将停止调整大小。最终结果是两列的宽度不相等。

JFoenix 库中的另一个控件 JFXDatePicker 也有同样的问题。

我的另一个限制是这个表单在SplitPane 内,所以我必须避免设置显式宽度。

我可以做些什么来解决这个问题?

编辑

考虑到这个问题的看法很少,我想我会在此处附上一个示例。

@Override
public void start(Stage primaryStage) throws Exception 
    VBox root = FXMLLoader.load(getClass().getResource("Test.fxml"));
    Scene sc = new Scene(root);
    primaryStage.setScene(sc);
    primaryStage.show();

FXML:

<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
    <padding>
        <Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
    </padding>
   <children>
      <GridPane hgap="6.0" vgap="6.0" VBox.vgrow="ALWAYS">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" />
          <ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" />
            <ColumnConstraints hgrow="SOMETIMES" />
            <ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Label text="Left 1" GridPane.halignment="RIGHT" />
            <Label text="Left 2" GridPane.halignment="RIGHT" GridPane.rowIndex="1" />
            <Label text="Left 3" GridPane.halignment="RIGHT" GridPane.rowIndex="2" />
            <Label text="Right 1" GridPane.columnIndex="2" GridPane.halignment="RIGHT" />
            <Label text="Right 2" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.rowIndex="1" />
            <Label text="Right 3" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.rowIndex="2" />
            <ComboBox maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" />
            <ComboBox maxWidth="1.7976931348623157E308" GridPane.columnIndex="3" />
            <ComboBox maxWidth="1.7976931348623157E308" GridPane.columnIndex="3" GridPane.rowIndex="2" />
         </children>
      </GridPane>
   </children>
</VBox>

结果:

如 GIF 所示,布局是我最初启动窗口时想要的布局。当我单击右侧的一个组合框时,该列突然增加了宽度并缩小了另一列。单击任何组合框时,我需要两列的宽度保持不变。

更新

似乎我错过了我的问题中的一些信息。我需要的最终结果是GridPane,在两个标签输入对中有 4 列。可以在对之间添加额外的列以在对之间添加额外的填充,但它是可选的。整个网格将处于可调整大小的环境中(例如在我的示例中 - 可调整大小的舞台)。我相信可调整大小的环境并非不合理,否则我会给所有列绝对大小(或者甚至使用任何Pane 并给它绝对位置)并且问题不会存在。

两个标签都必须始终可见(除非整个GridPane 缩小到非常小的尺寸),并且必须为输入控件(TextFieldComboBox 等)留出任何额外的空间。同样,如果GridPane 缩小,我希望输入列而不是标签列缩小。标签列应始终保持固定大小,此大小是显示所有标签而不出现省略号所需的最小大小。

由于最终表单混合了不同的输入控件,如果没有将ComboBox 调整为与同一列中的其他输入控件相同的宽度,它会使ComboBox 看起来很奇怪。我承认这个要求是我挑剔的。

我还希望两个输入列具有相同的宽度,并且必须始终保持不变。

另一个更新

我已为此创建了bug report,目前仍以 P3 优先级开放。

【问题讨论】:

【参考方案1】:

我只是尝试了设置,看看我能想出什么。这似乎工作。我在列上使用了百分比。

<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="162.0" prefWidth="326.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
    <padding>
        <!--Insets bottom="30.0" left="30.0" right="30.0" top="30.0" /-->
    </padding>
   <children>
      <GridPane hgap="6.0" vgap="6.0" VBox.vgrow="SOMETIMES">
        <columnConstraints>
          <ColumnConstraints halignment="RIGHT" hgrow="NEVER" percentWidth="15.0" />
          <ColumnConstraints hgrow="SOMETIMES" percentWidth="35.0" />
            <ColumnConstraints halignment="RIGHT" hgrow="NEVER" percentWidth="15.0" />
            <ColumnConstraints hgrow="SOMETIMES" percentWidth="35.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Label text="Left 1" GridPane.halignment="RIGHT" />
            <Label text="Left 2" GridPane.halignment="RIGHT" GridPane.rowIndex="1" />
            <Label text="Left 3" GridPane.halignment="RIGHT" GridPane.rowIndex="2" />
            <Label text="Right 1" GridPane.columnIndex="2" GridPane.halignment="RIGHT" />
            <Label text="Right 2" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.rowIndex="1" />
            <Label text="Right 3" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.rowIndex="2" />
            <ComboBox maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" />
            <ComboBox maxWidth="1.7976931348623157E308" GridPane.columnIndex="3" />
            <ComboBox maxWidth="1.7976931348623157E308" GridPane.columnIndex="3" GridPane.rowIndex="2" />
         </children>
      </GridPane>
   </children>
</VBox>

【讨论】:

当然,这会阻止 2 个组合框列随机改变它们的宽度,但我的标签列的宽度正在被缩放,这是我不想看到的。我需要标签列的宽度足以容纳所有标签。【参考方案2】:

这是一篇相当老的帖子,但我刚刚遇到了这个问题,发现最好的方法是为 ComboBox 和 GridPane 动态添加宽度处理程序,我有一个带有标签/的 4 x 2 网格组合/标签/组合很像你做的:

    cmbOne.setOnShowing(e -> detailsGrid.getColumnConstraints().get(1).setMaxWidth(cmbOne.getWidth()));
    cmbTwo.setOnShowing(e -> detailsGrid.getColumnConstraints().get(3).setMaxWidth(cmbTwo.getWidth()));
    detailsGrid.widthProperty().addListener(e -> 
        detailsGrid.getColumnConstraints().get(1).setMaxWidth(Double.MAX_VALUE);
        detailsGrid.getColumnConstraints().get(3).setMaxWidth(Double.MAX_VALUE);
    );

我设置我的两个组合框以在打开之前锁定 ColumnConstraint,然后当网格宽度发生变化(通过调整大小)时,我允许它再次增加大小。

【讨论】:

以上是关于JavaFX:GridPane 中的 ComboBox 导致不必要的大小调整的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX:将图像插入 GridPane

JavaFx GridPane 中的相对大小

可以决定 GridPane (JavaFX) 中的行数和列数

结合 javafx 2 ListView 和 GridPane 功能

JavaFX中GridPane的行居中对齐

如何在 JavaFX 的 GridPane 中删除“幽灵线”?