2013-04-18 3 views
6

Ho creato questa finestra di JavaFX con pulsante di chiusura:allineamento Button nella 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(); 

voglio visualizzare il pulsante nella parte inferiore della finestra di dialogo. L'ho usato per impostare l'allineamento: closeButton.setAlignment(Pos.BOTTOM_CENTER); ma per qualche motivo il pulsante viene visualizzato al centro della finestra di dialogo. Puoi dirmi come posso risolvere questo problema?

risposta

17

Se si desidera utilizzare un VBox per questo, il metodo che si sta cercando è:

VBox.setVgrow(node, Priority.ALWAYS);


Per impostazione predefinita un VBox sarà solo mettere i bambini uno sotto l'altro dalla parte superiore sinistra di dove lo metti. I bambini non si espandono per riempire tutta l'area verticale disponibile, a meno che non imposti un vincolo Vgrow su un bambino con un'altezza massima illimitata.

diversi modi è possibile ottenere il layout che cercate (ce ne sono anche altri):

  1. Utilizzare un StackPane invece di un VBox e allineare il pulsante con StackPane.setAlignment(closeButton, Pos.BOTTOM_CENTER);
  2. Utilizzare un AnchorPane invece di a VBox e impostare i vincoli sullo AnchorPane in modo appropriato.
  3. Utilizzare un spring region che è un'area vuota che si espande per riempire lo spazio vuoto.

Esempio regione primavera:

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); imposta l'allineamento delle cose (testo e grafica) all'interno del closeButton, non è l'allineamento del closeButton all'interno del suo genitore (che è ciò che vuoi veramente).


Per capire come funzionano i vincoli di layout, SceneBuilder è un buon strumento per giocare con e ScenicView può aiutare a problemi di layout di debug nel codice esistente.


Ecco alcuni esempi FXML del layout che è possibile caricare fino in SceneBuilder per vedere come le diverse opzioni di layout funzionano.

Tutti i campioni riportati di seguito possono essere facilmente scritti in java normale utilizzando l'API JavaFX se si preferisce. Li ho scritti in fxml perché rende i layout facili da vedere in anteprima in SceneBuilder.

campione FXML utilizzando uno 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

E la stessa cosa con alcune regioni molla:

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

E la stessa cosa con l'etichetta stessa impostato espandersi riempire lo spazio vuoto nella 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>