[Java] If the JavaFX screen size is below a certain size, display a scroll bar, and if it is above a certain size, maximize the inside node as much as possible.

3 minute read

Goal this time

I used ListView when creating a GUI application using JavaFx, but there were the following requests.

  1. I want to display the ListView as large as possible -→ The size changes automatically according to the size of the window
  2. When the window size is below a certain level, I want to stop resizing the ListView and make the window scroll.

It was difficult to meet such a request, so I wrote down the result.

The final aim is like this. The blue frame is a ListView, and when the screen size becomes smaller than the position where the button is, a scroll bar appears, indicating that there are parts next to it. Goal fxml.gif

Environment

java1.8 JavaFX Scene Builder 2.0

First from the result

The final component structure was realized as follows.

  • ScrollPane -AnchorPane -TextField -Button -ListView

![Screenshot 2020-07-09 13.20.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222220/41f0ac46-8272-70ad-925c-(33c225159b85.png)

Key points for setting each part

ScrollPane

  • Properties-Hbar/Vbar Policy is ```AS_NEEDED

    .

    ```

  • Layout-Set ```Fit To Width/Height

    to true(:heavy_check_mark:).

    ```

AnchorPane

  • Layout-Set ```Min Width/Height

    to the window size at which you want the scroll bar to start displaying.

    ```

ListView

  • Layout-Set all four sides of ```Anchor Pane Constrains

    as fixed values.

    ```

The road to realization Step by step

ListView settings linked to the window size

The combination of the following can realize “the size of the ListView changes in synchronization with the window size”.

AnchorPane and ListView

Use ```AnchorPane

.


What is ```AnchorPane```
>AnchorPane allows the edges of child nodes to be anchored to an offset from the anchor pane's edges.

For the node contained inside, the distance from the end of the parent AnchorPane can be fixed.

When adding Control to the child element of AnchorPane in SceneBulider, ```Anchor Pane Constraints
#### **` is displayed in Layout.`**

![Screenshot 2020-07-09 12.58.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222220/8e8d6df4-327b-3394-2973-(914790303314.png)

The ends of individual elements and the ends of AnchorPane are fixed by the values (distances) entered in these four text boxes. This is the only fixed value below. Fixed only below.gif

If you fix only one side, the size of the control does not change, but the display position changes.

This is what fixed the top and bottom. Fixed vertically.gif

It can be seen that when the top and bottom are fixed, the distance from the top and bottom has priority over the size of the control, and the size of the control expands and contracts.

This time, in order to display the size of the ListView as large as possible, it was found that for the ListView included in the AnchorPane, all four sides of ```Anchor Pane Constraints

should have fixed values.




#### AnchorPane in ScrollPane
ScrollPane has ```FitTo[Width|Height]Property
#### **`.`**

In Scene Builder this property Set in Fit To Width and Fit To Height of ```Layout

.



If you confirm the meaning of this ```Fit To Width/Height``` in the document,
>public final BooleanProperty fitToWidthProperty

>If true and if the contained node is a Resizable, then the node will be kept resized to match the width of the ScrollPane's viewport.If the contained node is not a Resizable, this value is ignored.

(Appropriate translation)
>When true, if the contained node is Risizable, the size of the node changes according to the width of the viewport of the ScrollPane. If the included node is not Resizable, this value is ignored.

So, change the size of ScrollPane (Window size in this case) by putting AnchorPane in ScrollPane and setting ```Fit To Width/Height``` to ```true
#### **`.`**

The size of Anchor Pane has changed in conjunction with. (AnchorPane is rather, JavaFX controls are all Resizeable)

Measures when the size of the window is less than a certain size

Next, “Display the scroll bar when the window size becomes smaller than a certain width.”

When FitTo[Width|Height]Property of ScrollPane is set to true, the size of the internal node changes in conjunction with the size of the ScrollPane, but Min of the internal node [Width|Height]・It seems that the size does not change beyond ```Max [Width|Height]

.



So, I set ```Min Width``` of AnchorPane in ScrollPane to a size that ```Button``` doesn't hide.


## The resulting fxml

#### **`Aim.fxml`**
```fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<ScrollPane fitToHeight="true" fitToWidth="true" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx= "http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
  <content>
    <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="343.0" prefWidth="486.0">
         <children>
            <TextField layoutX="14.0" layoutY="7.0" prefHeight="27.0" prefWidth="247.0" />
            <ListView layoutX="-4.0" layoutY="41.0" prefHeight="357.0" prefWidth="598.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="40.0 "/>
            <Button layoutX="272.0" layoutY="7.0" mnemonicParsing="false" text="Button" />
         </children></AnchorPane>
  </content>
</ScrollPane>