Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to align HBox by using BorderPane alignment in FXML?

Tags:

java

javafx

fxml

What am i trying is to align HBox Buttons to center in the Bottom in dialog box. I want to do this in fxml.However,BorderPane alignment is working in label. Here is code from my side.I think BorderPane.alignment="BOTTOM_CENTER" must work even if the tag is Bottom.

Class file:

package application;

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class HBoxDialog extends Application {

@Override
public void start(Stage primaryStage) {
    try {
        Parent root = FXMLLoader.load(getClass().getResource("HBoxDialog.fxml"));
        primaryStage.setScene(new Scene(root, 500, 100));
        primaryStage.show();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    launch(args);
}
}

FXML file:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1">

<top>
    <Label text="this is dialogbox" BorderPane.alignment="TOP_CENTER"/>
    <font>
        <Font size="35"/>
    </font>
</top>

<bottom>
    <HBox spacing="10">
        <Button text="Okay" prefWidth="90" BorderPane.alignment="BOTTOM_CENTER"/>
        <Button text="Cancel" prefWidth="90" BorderPane.alignment="BOTTOM_CENTER"/>
        <Button text="Help" prefWidth="90" BorderPane.alignment="BASELINE_RIGHT"/>
    </HBox>
</bottom>
</BorderPane>
like image 563
Under_stand Avatar asked Jan 29 '23 01:01

Under_stand


1 Answers

The BorderPane.alignment static property only makes sense for nodes whose parent is a BorderPane. The Buttons defined in your FXML file have an HBox as a parent, so setting the BorderPane.alignment property on the buttons will have no effect.

You can achieve the desired effect by centering the buttons within the HBox, simply by using the alignment property of the HBox (which positions the HBox's child nodes within its bounds):

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1">

    <top>
        <Label text="this is dialogbox"
            BorderPane.alignment="TOP_CENTER" />
        <font>
            <Font size="35" />
        </font>
    </top>

    <bottom>
        <HBox spacing="10" alignment="CENTER">
            <Button text="Okay" prefWidth="90" />
            <Button text="Cancel" prefWidth="90" />
            <Button text="Help" prefWidth="90" />
        </HBox>
    </bottom>
</BorderPane>

This gives

enter image description here

The reason that the Label needs BorderPane.alignment="CENTER" but the HBox needs alignment="CENTER" is because they have different resizable ranges, and in particular their max widths are different. The max width of a label, by default, is its preferred width, whereas the max width of an HBox is infinite. You can see this by setting background colors on them both:

    <Label text="this is dialogbox"
        BorderPane.alignment="TOP_CENTER" 
        style="-fx-background-color: aquamarine;"/>

    <!-- ... -->

    <HBox spacing="10" alignment="CENTER"
      style="-fx-background-color: lightskyblue;">

enter image description here

The alignment property positions the content of a node within its bounds. Since the label has no extra space within its bounds for the text to be positioned, with the default settings the alignment property will have no effect. On the other hand, the label is less wide than the top region of the border pane, so there is room to position it within that region. The BorderPane.alignment="CENTER" attribute centers the entire label within the top region of the border pane.

By contrast, the HBox itself already fills the entire width of the bottom region of the border pane. So there is no additional space to align it within that region, and so for the HBox, setting BorderPane.alignment="CENTER" will have no effect. On the other hand, there is more space in the HBox itself than is needed for the buttons, so the buttons (the content of the HBox) can be aligned within the HBox itself using the alignment="CENTER" property of the HBox.

If you want, you can change the max widths to achieve the same effect. For example:

<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.Double?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1">

    <top>
        <Label text="this is dialogbox"
            alignment="CENTER" 
            style="-fx-background-color: aquamarine;">

            <maxWidth>
             <Double fx:constant="MAX_VALUE"/>
            </maxWidth>

        </Label>
        <font>
            <Font size="35" />
        </font>
    </top>

    <bottom>
        <HBox spacing="10" alignment="CENTER"
          style="-fx-background-color: lightskyblue;">
            <Button text="Okay" prefWidth="90" />
            <Button text="Cancel" prefWidth="90" />
            <Button text="Help" prefWidth="90" />
        </HBox>
    </bottom>
</BorderPane>

allows the label to grow (like the default for the HBox), so now its alignment property has the desired effect:

enter image description here

or

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Region?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1">

    <top>
        <Label text="this is dialogbox"
            BorderPane.alignment="CENTER" 
            style="-fx-background-color: aquamarine;" />
        <font>
            <Font size="35" />
        </font>
    </top>

    <bottom>
        <HBox spacing="10" BorderPane.alignment="CENTER"
          style="-fx-background-color: lightskyblue;">

          <maxWidth>
              <Region fx:constant="USE_PREF_SIZE" />
          </maxWidth>

            <Button text="Okay" prefWidth="90" />
            <Button text="Cancel" prefWidth="90" />
            <Button text="Help" prefWidth="90" />
        </HBox>
    </bottom>
</BorderPane>

makes the HBox behave like the button, so now its BorderPane.alignment gives the desired effect:

enter image description here

like image 63
James_D Avatar answered Jan 30 '23 15:01

James_D