ComboBox item height bug
John Hendrikx
john.hendrikx at gmail.com
Sun Nov 9 18:50:24 UTC 2025
Hi,
Normally a cell will have computed values for each of the min/pref/max.
In your example, you were resetting the cells to USE_PREF_SIZE, but it
makes little difference in the reasoning. All the size of a cell
control (which is a label) will be the label's size to display its
text. Its preferred height will be say 20. Its minimum will also be 20
to avoid cuts off. Its maximum will be 20 because there is no reason
for it to take up more space. Those are the computes sizes. If you
change all to USE_PREF_SIZE, nothing changes (since pref is 20, min and
max will copy that). So:
- min/pref/max height are 20/20/20
- you set minimum to 6
- end result: pref height wins with 20 as it is within the range [min, max]
- you also set maximum to 1
- end result: pref height is now outside the min/max range, so it is
ignored; max is smaller than min, so it is ignored; min wins with 6
If you however set minimum to USE_PREF_SIZE (as was done in your
original code) or set it to 1, then you can use the pref size to change
it. Either because 1 is smaller than the pref size, and so changing
pref size to a smaller value won't make it go out of range; or in the
USE_PREF_SIZE case, because min will simply track the pref size value
and always change with it.
--John
On 09/11/2025 03:44, Cormac Redmond wrote:
> 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/6a2c2cc1/attachment-0001.htm>
More information about the openjfx-dev
mailing list