2013-04-18 5 views
6

J'ai créé cette boîte de dialogue JavaFX avec le bouton Fermer:alignement Button dans JavaFX

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(); 

Je veux afficher le bouton en bas de la boîte de dialogue. J'ai utilisé ceci pour régler l'alignement: closeButton.setAlignment(Pos.BOTTOM_CENTER); mais pour une raison quelconque, le bouton est affiché au centre de la boîte de dialogue. Pouvez-vous me dire comment je peux résoudre ce problème?

Répondre

17

Si vous souhaitez utiliser un VBox pour cela, la méthode que vous recherchez est:

VBox.setVgrow(node, Priority.ALWAYS);


Par défaut VBox sera juste placer les enfants un sous l'autre de la partie supérieure gauche de l'endroit où vous le placez. Les enfants ne se développent pas pour remplir toute la zone verticale disponible, sauf si vous définissez une contrainte Vgrow sur un enfant avec une hauteur max illimitée.

Quelques façons différentes, vous pouvez obtenir la mise en page que vous cherchez (il y a d'autres aussi):

  1. Utilisez un StackPane au lieu d'un VBox et aligner votre bouton avec StackPane.setAlignment(closeButton, Pos.BOTTOM_CENTER);
  2. Utilisez un AnchorPane au lieu de VBox et définissez correctement les contraintes sur le AnchorPane.
  3. Utilisez un spring region qui est une région vide qui se développe pour remplir l'espace vide.

région ressort de l'échantillon:

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); 

Appel closeButton.setAlignment(Pos.BOTTOM_CENTER); définit l'alignement des choses (texte et graphique) dans le closeButton, pas l'alignement de la closeButton au sein de son parent (qui est ce que vous voulez vraiment).


Pour comprendre comment fonctionnent les contraintes mise en page, SceneBuilder est un bon outil pour jouer avec et ScenicView peut aider à résoudre le débogage de mise en page dans le code existant.


Voici quelques exemples de FXML de votre mise en page que vous pouvez charger jusqu'à en SceneBuilder pour voir comment les différentes options de mise en page de travail.

Tous les exemples ci-dessous peuvent facilement être écrits en Java simple en utilisant l'API JavaFX si vous préférez. Je les ai écrits dans fxml car cela facilite la prévisualisation des mises en page dans SceneBuilder.

échantillon FXML utilisant un 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

Et la même chose avec certaines régions du printemps:

<?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> 

Et la même chose avec l'étiquette elle-même prête à se développer à remplir l'espace vide dans la 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>