I have a form with 4 columns - label, control, label, control. The width of the label is unknown. I need the labels to always be fully displayed, meaning they should not be truncated, so only the width of the controls should change. If possible, I want the first and third columns (the ones with controls) to have the same width. So, column1Width should equal column3Width.
If I only use textfields, there is no issue. But when I added a stretching ComboBox and a value is selected in this ComboBox then column1Width != column3Width.
This is my code:
public class NewMain extends Application {
enum Test { FOO, BAR }
@Override
public void start(Stage stage) {
GridPane gridPane = new GridPane();
gridPane.setHgap(10);
gridPane.setVgap(10);
gridPane.setPadding(new Insets(10));
textFieldRow(gridPane, 0);
textFieldRow(gridPane, 1);
Label label1 = new Label("Label AAAAA BBBBB:");
label1.setMinWidth(Region.USE_PREF_SIZE);
var comboBox = new ComboBox<Test>();
comboBox.setItems(FXCollections.observableArrayList(Test.values()));
gridPane.add(label1, 0, 2);
gridPane.add(comboBox, 1, 2);
comboBox.setMaxWidth(Double.MAX_VALUE);
Scene scene = new Scene(gridPane, 600, 200);
stage.setScene(scene);
stage.show();
}
private void textFieldRow(GridPane gridPane, int index) {
Label label1 = new Label("Label AAAAA BBBBB:");
label1.setMinWidth(Region.USE_PREF_SIZE);
TextField textField1 = new TextField();
GridPane.setHgrow(textField1, Priority.ALWAYS);
textField1.setMinWidth(10);
Label label2 = new Label("Label CCCCCC DDDDDD:");
label2.setMinWidth(Region.USE_PREF_SIZE);
TextField textField2 = new TextField();
GridPane.setHgrow(textField2, Priority.ALWAYS);
textField2.setMinWidth(10);
gridPane.add(label1, 0, index);
gridPane.add(textField1, 1, index);
gridPane.add(label2, 2, index);
gridPane.add(textField2, 3, index);
}
public static void main(String[] args) {
launch(args);
}
}
And this is the result:
As you can see, at the beginning, everything works well. The width of column 1 is equal to the width of column 3. However, when a value is selected in the ComboBox, column 1 becomes wider than column 3.
Could anyone say how to fix it?
I have a form with 4 columns - label, control, label, control. The width of the label is unknown. I need the labels to always be fully displayed, meaning they should not be truncated, so only the width of the controls should change. If possible, I want the first and third columns (the ones with controls) to have the same width. So, column1Width should equal column3Width.
If I only use textfields, there is no issue. But when I added a stretching ComboBox and a value is selected in this ComboBox then column1Width != column3Width.
This is my code:
public class NewMain extends Application {
enum Test { FOO, BAR }
@Override
public void start(Stage stage) {
GridPane gridPane = new GridPane();
gridPane.setHgap(10);
gridPane.setVgap(10);
gridPane.setPadding(new Insets(10));
textFieldRow(gridPane, 0);
textFieldRow(gridPane, 1);
Label label1 = new Label("Label AAAAA BBBBB:");
label1.setMinWidth(Region.USE_PREF_SIZE);
var comboBox = new ComboBox<Test>();
comboBox.setItems(FXCollections.observableArrayList(Test.values()));
gridPane.add(label1, 0, 2);
gridPane.add(comboBox, 1, 2);
comboBox.setMaxWidth(Double.MAX_VALUE);
Scene scene = new Scene(gridPane, 600, 200);
stage.setScene(scene);
stage.show();
}
private void textFieldRow(GridPane gridPane, int index) {
Label label1 = new Label("Label AAAAA BBBBB:");
label1.setMinWidth(Region.USE_PREF_SIZE);
TextField textField1 = new TextField();
GridPane.setHgrow(textField1, Priority.ALWAYS);
textField1.setMinWidth(10);
Label label2 = new Label("Label CCCCCC DDDDDD:");
label2.setMinWidth(Region.USE_PREF_SIZE);
TextField textField2 = new TextField();
GridPane.setHgrow(textField2, Priority.ALWAYS);
textField2.setMinWidth(10);
gridPane.add(label1, 0, index);
gridPane.add(textField1, 1, index);
gridPane.add(label2, 2, index);
gridPane.add(textField2, 3, index);
}
public static void main(String[] args) {
launch(args);
}
}
And this is the result:
As you can see, at the beginning, everything works well. The width of column 1 is equal to the width of column 3. However, when a value is selected in the ComboBox, column 1 becomes wider than column 3.
Could anyone say how to fix it?
Share Improve this question asked Jan 18 at 11:03 SilverCubeSilverCube 6862 silver badges12 bronze badges 3- Don't you just need to bind the width property of the controls so that when the width of one changes, the width of the other is set to the same value? – Abra Commented Jan 18 at 11:29
- @Abra I tried to use different bindings, but no one worked. – SilverCube Commented Jan 18 at 12:05
- 3 This definitely seems like a JavaFX bug. A ComboBox’s preferred size should not change the first time (or any time) its item list is shown. – VGR Commented Jan 18 at 12:50
1 Answer
Reset to default 0I’m pretty sure this is a bug in JavaFX. It might or might not be related to this open bug, though the page says it only affects JavaFX 8 and 9.
As a workaround, you can create a subclass of ComboBox which never updates its preferred size unless the item list changes:
private static class ComboBoxWithSizeFix<T>
extends ComboBox<T> {
private double fixedWidth;
private final ListChangeListener<T> itemsListener = change -> {
if (change.wasAdded() || change.wasRemoved()) {
fixedWidth = 0;
}
};
ComboBoxWithSizeFix() {
itemsProperty().addListener((o, oldList, newList) -> {
fixedWidth = 0;
oldList.removeListener(itemsListener);
newList.addListener(itemsListener);
});
getItems().addListener(itemsListener);
}
ComboBoxWithSizeFix(ObservableList<T> items) {
super(items);
itemsProperty().addListener((o, oldList, newList) -> {
fixedWidth = 0;
oldList.removeListener(itemsListener);
newList.addListener(itemsListener);
});
getItems().addListener(itemsListener);
}
@Override
protected double computePrefWidth(double height) {
if (fixedWidth == 0) {
fixedWidth = superputePrefWidth(height);
}
return fixedWidth;
}
}