> > When it comes to size priorities (min, pref and max), minimum always wins, > then comes maximum, then comes preferred. > - 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
Is this documented somewhere? I'd think it would answer a lot of confusing questions. On Sun, Nov 9, 2025 at 8:50 PM John Hendrikx <[email protected]> wrote: > 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 <[email protected]> > 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 >> >>
