ComboBox item height bug
Cormac Redmond
credmond at certak.com
Sun Nov 9 02:44:41 UTC 2025
Hi John,
Thanks for the reply & details. One remaining question in my previous mail
however, was why a max *needs* to be set for min to "win"...this still
didn't make sense.
Similarly, I had already tried prefHeight on its own, but it has no effect
(unless it's set to number higher than the computed size of the cell, in
which case it would increase the size). Setting prefHeight and minHeight
together though, can achieve setting a "max height" though, just like
setting a maxHeight and minHeight as per my previous mail.
But I've noticed that values prefHeight, minHeight, maxHeight are all
defaulted to USE_COMPUTED_SIZE (-1)..., *not USE_PREF_SIZE* as you
mentioned, and I assumed.
So this explains the above behaviour and why several need to be set:
otherwise computed size wins one way or another.
Although confusing initially, I assume there's no bug here and that the
developer needs to always check the underlying nature of how pref/min/max
default values are set for any node, in order to know what and how to
override their settings...?
If you want some validation, you can see these -1 defaults, via a simpler
example:
public class ComboBoxHeightBug2 extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage) {
ComboBox<Object> cb = new ComboBox<>();
cb.getItems().addAll("Apple", "Banana", "Carrot", "Lettuce");
cb.setCellFactory(_ -> new ListCell<>() {
protected void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
} else if (item instanceof Separator) {
setText(null);
setGraphic((Separator) item);
setDisable(true);
} else {
System.out.println("minHeight: " + getMinHeight()); //
-1
System.out.println("maxHeight: " + getMaxHeight()); //
-1
System.out.println("prefHeight: " + getPrefHeight());
// -1
setText(item.toString());
setGraphic(null);
setStyle("");
}
}
});
cb.getSelectionModel().selectFirst();
stage.setScene(new Scene(cb, 200, 100));
stage.show();
}
}
Kind Regards,
Cormac
On Sun, 9 Nov 2025 at 00:06, John Hendrikx <john.hendrikx at gmail.com> wrote:
> What you are likely seeing is that the minimum always wins over the other
> values.
>
> The minimum height is set to the constant USE_PREF_SIZE, which means that
> it will take the preferred size for the minimum height.
>
> When it comes to size priorities (min, pref and max), minimum always wins,
> then comes maximum, then comes preferred.
>
> So in this case, the preferred size is say 20. The minimum follows the
> preferred, also 20. You set maximum to 1. Minimum > Maximum, so Maximum
> is ignored.
>
> What you could try is set preferred size smaller instead; there should be
> no need to change minimum or maximum then.
>
> --John
> On 08/11/2025 21:30, Cormac Redmond wrote:
>
> Hi,
>
> I have found a height bug when I am trying to reduce the height of one
> ComboBox item (a Separator) in a simple ComboBox.
>
> One would expect that to achieve this, you'd set the maximum height for
> that particular ListCell; but this has no effect.
>
> Instead what I need to do is set the *minimum* height (but to the value I
> wish to be the maximum height), and I must *also *set the *maximum *height
> to any value (if I do not, my minimum height (i.e., my desired maximum)
> gets ignored)...
>
> For example, if I want the maximum height of this Separator to be 6, I
> must set the minimum height to 6 and I must set the maximum height to
> anything, even 1.
>
> Obviously this is counter-intuitive and doesn't make any logical sense.
>
> Example to reproduce (running from JFX master branch):
>
> public class ComboBoxHeightBug extends Application {
> public static void main(String[] args) {
> launch(args);
> }
>
> public void start(Stage stage) {
> ComboBox<Object> cb = new ComboBox<>();
> cb.getItems().addAll("Apple", "Banana", new Separator() ,
> "Carrot", "Lettuce");
> cb.setCellFactory(_ -> new ListCell<>() {
> protected void updateItem(Object item, boolean empty) {
> super.updateItem(item, empty);
> if (empty || item == null) {
> setText(null);
> setGraphic(null);
> setStyle("");
> // Set back to default
> setMinHeight(USE_PREF_SIZE);
> setMaxHeight(Double.MAX_VALUE);
> } else if (item instanceof Separator) {
> setText(null);
> setGraphic((Separator) item);
> setDisable(true);
> setMinHeight(6); // This is required for any "max
> height" to apply, and appears to be the value that is used to determine
> height
> setMaxHeight(1); // Setting this (to 6) should work on
> its own, it doesn't, the value appears irrelevant -- but it MUST be set to
> get the separator height to be 6
> } else {
> setText(item.toString());
> setGraphic(null);
> setStyle("");
> // Set back to default
> setMinHeight(USE_PREF_SIZE);
> setMaxHeight(Double.MAX_VALUE);
> }
> }
> });
>
> cb.getSelectionModel().selectFirst();
> stage.setScene(new Scene(cb, 200, 100));
> stage.show();
> }
> }
>
> Note: I have noticed a few issues like this in general, whereby it
> requires trial and error to get *some* desired height to apply; without
> any apparent logic as to how these values are being arrived at or how
> they're triggered to be used (I have logged bugs before on this)...
>
>
> Kind Regards,
> Cormac
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20251109/3db1eeca/attachment.htm>
More information about the openjfx-dev
mailing list