简体   繁体   中英

JavaFX: ComboBox in GridPane causes unnecessary resizing

I have a GridPane with 5 columns. These are my hgrow setting for the column constraints respectively.

  1. SOMETIMES
  2. ALWAYS
  3. SOMETIMES (fixed sized)
  4. SOMETIMES
  5. ALWAYS

The whole GridPane is basically a layout for a two-column form. My columns 1 and 4 (index 0 and 3) are field labels, while columns 2 and 5 are the input fields ( TextField etc). Column 3 is just a fixed-width padding between the two form columns.

I have some ComboBox in my form - some are on the left column, some on the right column. I have set the max width of all the ComboBox to MAX_VALUE .

When the form loads, the layout looks like what I had intended (both input-field columns have equal width). However, when I click on any of the ComboBox , it would cause the column that the clicked ComboBox is on to increase in width - which causes the other input-field column to decrease by the same amount.

I can alternate clicking on the ComboBox on the left and right, and the widths of both columns would keep changing. The change would get smaller and smaller and eventually the columns would stop resizing. The end result is that the two columns are not equal in width.

I have the same problem for another control JFXDatePicker from JFoenix library.

Another constraint I have is that this form is within a SplitPane , so I have to avoid setting explicit widths.

What can I do to fix this problem?

Edit

I guess I will attach a sample here considering how little view this question has.

@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>

The result:

结果

As shown in the GIF, the layout is what I wanted when the window is initially launched. When I clicked on one of the combobox at the right side, the column suddenly increased its width and shrunk the other column. I need the width of both columns to remain constant when any of the comboboxes are clicked.

Update

It seems like I had missed out some information in my question. The final result I need is a GridPane with 4 columns in two label-input pairs. An extra column can be added between the pairs to add additional padding between the pairs, but it's optional. The whole grid will be in a resizable environment (for example in my example - a resizable Stage). I believe resizable environment is not unreasonable, otherwise I would have given all columns absolute sizes (or even use any Pane and gave it absolute position) and the problem wouldn't have existed.

Both the labels must always be visible (unless the whole GridPane is reduced to a terribly small size), and any additional space must be given to the input controls ( TextField , ComboBox etc). Similarly, if the GridPane is shrunk, I expect the input columns to shrink instead of the label columns. The label columns should maintain a fixed size throughout, and this size is the minimum size that is needed to display all labels without ellipsis appearing.

As the final form has a mixture of different input controls, it would make the ComboBox look weird if it is not resized to the same width as other input controls in the same column. I admit that this requirement is me being picky.

I also expect both the input columns to have the same width, and that this must remain true at all times.

Another Update

I have made a bug report on this, and it is currently still open with a P3 priority.

I just played with the setting to see what I could come up with. This appears to be working. I used percentages on the columns.

<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>

This is a pretty old post, but I just ran into this issue and found that the best way to do it is to dynamically add width handlers to both the ComboBox and the GridPane, I have a 4 x 2 grid with label/combo/label/combo much like you do:

    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);
    });

I setup my two combo boxes to lock down the ColumnConstraint prior to opening, and then when the grid width is changed (by a resize) I allow it to increase size again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM