Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Button alignment in JavaFX

I created this JavaFX dialog with Close button:

final int xSize = 300;
final int ySize = 280;
final Color backgroundColor = Color.WHITE;
final String text = "SQL Browser Version 1.0";

final Stage aboutDialog = new Stage();
aboutDialog.initModality(Modality.WINDOW_MODAL);

Button closeButton = new Button("Close");
closeButton.setAlignment(Pos.BOTTOM_CENTER);

closeButton.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent arg0) {
        aboutDialog.close();
    }
});

Scene aboutDialogScene = new Scene(VBoxBuilder.create()
    .children(new Text(text), closeButton)
    .alignment(Pos.CENTER)
    .padding(new Insets(10))
    .build(), xSize, ySize, backgroundColor);

aboutDialog.setScene(aboutDialogScene);
aboutDialog.show();

I want to display the button at the bottom of the dialog. I used this to set the alignment: closeButton.setAlignment(Pos.BOTTOM_CENTER); but for some reason the button is displayed at the center of the dialog. Can you tell me how I can fix this?

like image 880
Peter Penzov Avatar asked Apr 18 '13 13:04

Peter Penzov


People also ask

How do I center a button in JavaFX?

Centering the ButtonshbButtons. setAlignment(Pos. CENTER); The setAlignment() method for the HBox pane centers the HBox pane within its layout area and also centers the nodes within the HBox pane.

How do I center a button in JavaFX GridPane?

You need to set alignment for your GridPane as alignment="center" and all elements will be aligned in center. Update You can align your buttons in center like this. After this update you also can delete columnSpan attribute from each node. Save this answer.

How to align HBox?

Set the spacing by passing a double value of space as an argument to the constructor. Set the alignment of the HBox using the setAlignment() function. Then create a label and add it to the hbox. Add some buttons to the HBox using the getChildren().

How to set position of HBox JavaFX?

You can set the margin for child nodes of a JavaFX HBox using the static setMargin() method. Here is an example of setting the margin around a JavaFX Button using the setMargin() method: Button button1 = new Button("Button 1"); HBox hbox = new HBox(button1); HBox. setMargin(button1, new Insets(10, 10, 10, 10));


1 Answers

If you want to use a VBox for this, the method you are looking for is:

VBox.setVgrow(node, Priority.ALWAYS);


By default a VBox will just place children one under the other from the top left of where you place it. The children don't expand to fill all of the available vertical area, unless you set a Vgrow constraint on a child with an unbounded max height.

A few different ways you can get the layout you seek (there are others as well):

  1. Use a StackPane instead of a VBox and align your button with StackPane.setAlignment(closeButton, Pos.BOTTOM_CENTER);
  2. Use an AnchorPane instead of a VBox and set constraints on the AnchorPane appropriately.
  3. Use a spring region which is an empty Region which expands to fill empty space.

Sample spring region:

Region topSpring    = new Region();
Region bottomSpring = new Region();
Scene aboutDialogScene = new Scene(VBoxBuilder.create()
        .children(topSpring, new Text(text), bottomSpring, closeButton)
        .alignment(Pos.CENTER)
        .padding(new Insets(10))
        .build(), xSize, ySize, backgroundColor);
VBox.setVgrow(topSpring, Priority.ALWAYS);
VBox.setVgrow(bottomSpring, Priority.ALWAYS);

Calling closeButton.setAlignment(Pos.BOTTOM_CENTER); sets the alignment of things (text and graphic) within the closeButton, not the alignment of the closeButton within it's parent (which is what you really want).


For understanding how layout constraints work, SceneBuilder is a good tool to play around with and ScenicView can help debug layout issues in existing code.


Here are a few FXML samples of your layout that you can load up into SceneBuilder to see how the different layout options work.

All of the samples below can easily be written in plain java using the JavaFX API if you prefer. I wrote them in fxml as it makes the layouts easy to preview in SceneBuilder.

FXML sample using a StackPane:

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

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

<StackPane id="StackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="280.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml">
  <children>
    <Label text="SQL Browser Version 1.0" />
    <Button mnemonicParsing="false" text="Button" StackPane.alignment="BOTTOM_CENTER" />
  </children>
  <padding>
    <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
  </padding>
</StackPane>

snapshot of fxml

And the same thing with some spring regions:

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

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

<VBox alignment="CENTER" prefHeight="280.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml">
  <children>
    <Region prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS" />
    <Label text="SQL Browser Version 1.0" />
    <Region prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS" />
    <Button mnemonicParsing="false" text="Close" />
  </children>
</VBox>

And the same thing with the label itself set to expand to fill empty space in the VBox:

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

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

<VBox alignment="CENTER" prefHeight="280.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml">
  <children>
    <Label maxHeight="1.7976931348623157E308" text="SQL Browser Version 1.0" VBox.vgrow="ALWAYS" />
    <Button mnemonicParsing="false" text="Close" />
  </children>
  <padding>
    <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
  </padding>
</VBox>
like image 144
jewelsea Avatar answered Oct 13 '22 16:10

jewelsea