2

JavaFx 8 maxWidth Ignored

The maxWidth is ignored for HBox children with wider content.

For example, the center Pane below is far too large, extending under the right column (Pane):

 <HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="1000.0" prefWidth="1236.0">
      <children>
           <Pane fx:id="leftPane" maxHeight="10000.0" maxWidth="120.0" minHeight="400.0" minWidth="100.0" prefHeight="10000.0" prefWidth="120.0"/>
           <Pane fx:id="centerPane" maxHeight="10000.0" maxWidth="10000.0" minHeight="400.0" minWidth="120.0" prefHeight="10000.0" >
           </Pane>
           <Pane fx:id="rightPane" maxHeight="10000.0" maxWidth="120.0" minHeight="400.0" minWidth="100.0" prefHeight="10000.0" prefWidth="120.0" />
      </children>
 </HBox>

There is no conflicting CSS, such as defining a percentage, or otherwise setting a content width.

How to Make maxWidth a Hard-Limit?

Is there a way to make JavaFX recompute the child pane sizes each time the child content changes, while never exceeding the maxWidth of the parent?

Community
  • 1
  • 1
Brent Faust
  • 9,103
  • 6
  • 53
  • 57

2 Answers2

6

From JavaFX Pane documentation:

This class may be used directly in cases where absolute positioning of children is required since it does not perform layout beyond resizing resizable children to their preferred sizes. It is the application's responsibility to position the children since the pane leaves the positions alone during layout.

So, you cannot reach your goal by using basic Panes as children. Better try to use StackPanes instead:

A stackpane's parent will resize the stackpane within the stackpane's resizable range during layout.

A stackpane's unbounded maximum width and height are an indication to the parent that it may be resized beyond its preferred size to fill whatever space is assigned to it.

Take a look at this example (I added background colors to the StackPanes, since I used SceneBuilder to test the behavior) and tell me please if it satisfies your needs:

<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="1000.0" prefWidth="1236.0" style="-fx-background-color: lightblue;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
  <children>
       <StackPane fx:id="leftPane" maxHeight="10000.0" maxWidth="120.0" minHeight="400.0" minWidth="100.0" prefHeight="10000.0" prefWidth="120.0" style="-fx-background-color: red;" />
       <StackPane fx:id="centerPane" maxHeight="10000.0" maxWidth="10000.0" minHeight="400.0" minWidth="120.0" prefHeight="10000.0" style="-fx-background-color: white;"> 
       <children>
        <Label prefWidth="999.0" text="Label of example. Label of example. Label of example. Label of example. Label of example. Label of example. Label of example. Label of example. Label of example. Label of example. Label of example. " />
     </children></StackPane>
       <StackPane fx:id="rightPane" maxHeight="10000.0" maxWidth="120.0" minHeight="400.0" minWidth="100.0" prefHeight="10000.0" prefWidth="120.0" style="-fx-background-color: green;" />
  </children></HBox>

You can also use other Pane or Box components instead.

Update:

The previous example makes the center Pane to dynamically adjust in function of the width of its children, fulfilling the parent Pane if needed, but never exceeding its maximum width. So, if you want the Pane to always fill the width of its parent, a big enough preferred width must be added to the center Pane.

<StackPane fx:id="centerPane" maxHeight="10000.0" minHeight="400.0" prefHeight="10000.0" prefWidth="1000.0"/>
Community
  • 1
  • 1
Alexander Ortiz
  • 529
  • 7
  • 14
  • Perfect. And by adding to the centerPane `prefWidth="9999"`, it fills the horizontal space between the two side columns! – Brent Faust Aug 26 '15 at 22:26
  • Ah, I see. You did that with the Label child. It's better to have it on the parent (centerPane) in this case, so the center column size is always as wide as possible, regardless of the width of its children. – Brent Faust Aug 26 '15 at 22:28
  • Oh, I misunderstood part of your question. I thought you wanted to dynamically change the width of your center Pane in function of its children, so it would not change its preferred width if there were no children that exceeded that size. Since you want to make the center Pane as wide as possible, your previous comment hit the spot! – Alexander Ortiz Aug 27 '15 at 07:03
  • Is there no setting to make Pane honor the maxWidth (so wrapping everything in StackPane isn't necessary)? – Brent Faust Aug 27 '15 at 22:32
  • You can force a min, max and preferred size to the Pane by always considering the size of its parent and its brothers, but any change in it exceeding the maximum size you wanted in your parent won't preserve your scheme. You should consider if you really need to use Panes instead of Boxes or another type of Panes, since these components offer a major versatility than their base component :) – Alexander Ortiz Aug 28 '15 at 11:34
1

To make container resize automatically according to its children size use javafx constants like:

centerPane.setMinWidth(Control.USE_PREF_SIZE);
smac89
  • 39,374
  • 15
  • 132
  • 179