Javafx 组件应始终位于 AnchorPane 的中心

Javafx components should always be in center of AnchorPane

我希望我的 Javafx 组件(例如分别包装在 VBox 中的标签、TextField)保持在 window 的中心,即使它已调整大小。见附件图片。目前这些组件包含在 anchorPane 中。 FXML 文件代码如下。请给我一个如何做到这一点的想法。谢谢

Image for small size window where components are in middle.

Full sized window but component position is not changed.

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

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

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="650.0" minWidth="850.0" prefHeight="650.0" prefWidth="850.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
  <HBox layoutY="-1.0" minWidth="500.0" prefHeight="653.0" prefWidth="850.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
     <children>
        <MenuBar layoutY="-1.0" minWidth="500.0" prefHeight="30.0" prefWidth="850.0" HBox.hgrow="ALWAYS">
          <menus>
            <Menu mnemonicParsing="false" text="Account">
              <items>
                <MenuItem fx:id="menuItemCreate" mnemonicParsing="false" text="Create" />
                    <MenuItem fx:id="menuItemUpdate" mnemonicParsing="false" text="Update" />
                    <MenuItem fx:id="menuItemDelete" mnemonicParsing="false" text="Delete" />
                    <MenuItem fx:id="menuItemLedger" mnemonicParsing="false" text="Ledger" />
              </items>
            </Menu>
            <Menu mnemonicParsing="false" text="In Stock">
              <items>
                <MenuItem fx:id="menuItemAddItem" mnemonicParsing="false" text="Add items" />
                    <MenuItem fx:id="menuItemInventory" mnemonicParsing="false" text="Inventory" />
              </items>
            </Menu>
            <Menu mnemonicParsing="false" text="Reports">
              <items>
                <MenuItem fx:id="menuItemSalesReport" mnemonicParsing="false" text="Sales report" />
                    <MenuItem fx:id="menuItemProfitReport" mnemonicParsing="false" text="Profit report" />
                    <MenuItem fx:id="menuItemRcvables" mnemonicParsing="false" text="Receivables" />
              </items>
            </Menu>
          </menus>
        </MenuBar>
     </children>
  </HBox>
  <AnchorPane fx:id="anchorPaneUpdate" layoutY="30.0" prefHeight="620.0" prefWidth="850.0" visible="false">
     <children>
        <VBox layoutX="300.0" layoutY="150.0" prefHeight="120.0" prefWidth="60.0" spacing="30.0">
           <children>
              <Label alignment="BASELINE_RIGHT" prefWidth="60.0" text="Full Name" BorderPane.alignment="CENTER" VBox.vgrow="NEVER" />
              <Label alignment="BASELINE_RIGHT" layoutX="10.0" layoutY="10.0" prefWidth="60.0" text="Address" VBox.vgrow="NEVER" />
              <Label alignment="BASELINE_RIGHT" layoutX="10.0" layoutY="27.0" prefWidth="60.0" text="CNIC" VBox.vgrow="NEVER" />
              <Label alignment="BASELINE_RIGHT" layoutX="10.0" layoutY="44.0" prefWidth="60.0" text="Mobile #" VBox.vgrow="NEVER" />
           </children>
        </VBox>
        <VBox layoutX="400.0" layoutY="150.0" spacing="20.0">
           <children>
              <TextField layoutX="10.0" layoutY="10.0" promptText="Full name" />
              <TextField promptText="Full name" VBox.vgrow="NEVER" />
              <TextField promptText="Current address" VBox.vgrow="NEVER" />
              <TextField promptText="XXXXX-XXXXXXX-X" VBox.vgrow="NEVER" />
              <TextField promptText="XXXX-XXXXXXX" VBox.vgrow="NEVER" />
              <Button mnemonicParsing="false" prefWidth="70.0" text="Create" />
           </children>
        </VBox>
        <Label layoutX="50.0" layoutY="80.0" text="Update a customer account">
           <font>
              <Font name="Arial Narrow Bold" size="17.0" />
           </font>
        </Label>
     </children></AnchorPane>
  <AnchorPane fx:id="anchorPaneDelete" layoutY="30.0" prefHeight="620.0" prefWidth="850.0" visible="false" />
  <AnchorPane fx:id="anchorPaneLedger" layoutY="30.0" prefHeight="620.0" prefWidth="850.0" visible="false" />
  <AnchorPane fx:id="anchorPaneAddItem" layoutY="30.0" prefHeight="620.0" prefWidth="850.0" visible="false" />
  <AnchorPane fx:id="anchorPaneInventory" layoutY="30.0" prefHeight="620.0" prefWidth="850.0" visible="false" />
  <AnchorPane fx:id="anchorPaneSalesReport" layoutY="30.0" prefHeight="620.0" prefWidth="850.0" visible="false" />
  <AnchorPane fx:id="anchorPaneProfitReport" layoutY="30.0" prefHeight="620.0" prefWidth="850.0" visible="false" />
  <AnchorPane fx:id="anchorPanerRcvable" layoutY="30.0" prefHeight="620.0" prefWidth="850.0" visible="false" />
  <VBox layoutX="300.0" layoutY="230.0" AnchorPane.bottomAnchor="199.0" AnchorPane.leftAnchor="300.0" AnchorPane.rightAnchor="301.0" AnchorPane.topAnchor="200.0">
     <children>
        <StackPane fx:id="pane_main" minHeight="200.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
           <children>
              <Group>
                 <children>
                    <VBox spacing="10.0">
                       <children>
                          <HBox prefHeight="30.0" prefWidth="330.0" spacing="30.0">
                             <children>
                                <Label alignment="BASELINE_RIGHT" prefWidth="80.0" text="Search Name" />
                                <TextField minWidth="130.0" prefWidth="130.0" promptText="Enter name" />
                             </children>
                          </HBox>
                          <Label alignment="BASELINE_RIGHT" prefWidth="80.0" text="Details:" />
                          <Separator minWidth="165.0" prefHeight="10.0" prefWidth="330.0" />
                          <HBox spacing="30.0">
                             <children>
                                <VBox spacing="30.0">
                                   <children>
                                      <Label alignment="BASELINE_RIGHT" prefWidth="80.0" text="Full Name" VBox.vgrow="NEVER" />
                                      <Label alignment="BASELINE_RIGHT" layoutX="10.0" layoutY="10.0" prefWidth="80.0" text="Address" VBox.vgrow="NEVER" />
                                      <Label alignment="BASELINE_RIGHT" layoutX="10.0" layoutY="10.0" prefWidth="80.0" text="CNIC" VBox.vgrow="NEVER" />
                                      <Label alignment="BASELINE_RIGHT" layoutX="20.0" layoutY="20.0" prefWidth="80.0" text="Mobile #" VBox.vgrow="NEVER" />
                                   </children>
                                </VBox>
                                <VBox layoutX="100.0" spacing="20.0">
                                   <children>
                                      <TextField minWidth="130.0" prefWidth="130.0" promptText="Full name" VBox.vgrow="NEVER" />
                                      <TextField minWidth="130.0" prefWidth="130.0" promptText="Current address" VBox.vgrow="NEVER" />
                                      <TextField minWidth="130.0" prefWidth="130.0" promptText="XXXXX-XXXXXXX-X" VBox.vgrow="NEVER" />
                                      <TextField minWidth="130.0" prefWidth="130.0" promptText="XXXX-XXXXXXX" VBox.vgrow="NEVER" />
                                      <Button minWidth="70.0" mnemonicParsing="false" prefWidth="70.0" text="Create" VBox.vgrow="NEVER" />
                                   </children>
                                </VBox>
                             </children>
                          </HBox>
                          <Label text="Update a customer account" VBox.vgrow="NEVER">
                             <font>
                                <Font name="Arial Narrow Bold" size="17.0" />
                             </font>
                          </Label>
                       </children>
                    </VBox>
                 </children>
              </Group>
           </children>
        </StackPane>
     </children>
  </VBox>
  </children>
  </AnchorPane>

你应该把所有你喜欢的东西放在一个组的中间。然后将您的组放在 StackPane 中。这样您的组始终位于 StackPane 的中心。根据需要定义 StackPane 的大小,或者将其绑定到 AnchorPane 父级,如示例所示:

在fxml中应该变成这样:

    <AnchorPane>
       <children>
          <StackPane AnchorPane.bottomAnchor="0.0" AnchorPane.left...>
             <children>
                <Group StackPane.alignment="CENTER">
                   <children>
                      ...       
                    </children>
                 </Group>
              </children>
            </StackPane>
          </children>
     </AnchorPane>

这应该可以解决您的问题。

我很快就把它放在一起了。在您的代码中有许多 AnchorPanes,中间的表单元素位于不同的位置,我认为这让一切变得更难。相反,我使用了 GridPane:

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

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

<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <MenuBar>
            <menus>
                <Menu text="Account">
                    <items>
                        <MenuItem fx:id="menuItemCreate" text="Create" />
                        <MenuItem fx:id="menuItemUpdate" text="Update" />
                        <MenuItem fx:id="menuItemDelete" text="Delete" />
                        <MenuItem fx:id="menuItemLedger" text="Ledger" />
                    </items>
                </Menu>
                <Menu text="In Stock">
                    <items>
                        <MenuItem fx:id="menuItemAddItem" text="Add items" />
                        <MenuItem fx:id="menuItemInventory" text="Inventory" />
                    </items>
                </Menu>
                <Menu text="Reports">
                    <items>
                        <MenuItem fx:id="menuItemSalesReport" text="Sales report" />
                        <MenuItem fx:id="menuItemProfitReport" text="Profit report" />
                        <MenuItem fx:id="menuItemRcvables" text="Receivables" />
                    </items>
                </Menu>
            </menus>
        </MenuBar>
        <BorderPane VBox.vgrow="ALWAYS">
            <top>
                <Label text="Create a new customer account" BorderPane.alignment="CENTER">
                    <font>
                        <Font name="Arial Narrow Bold" size="17.0" />
                    </font>
                    <BorderPane.margin>
                        <Insets />
                    </BorderPane.margin>
                </Label>
            </top>
            <center>
                <GridPane alignment="TOP_CENTER" hgap="10.0" vgap="5.0">
                    <columnConstraints>
                        <ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" percentWidth="0.0" />
                        <ColumnConstraints hgrow="SOMETIMES" percentWidth="0.0" />
                    </columnConstraints>
                    <rowConstraints>
                        <RowConstraints />
                        <RowConstraints />
                        <RowConstraints />
                        <RowConstraints />
                    </rowConstraints>
                    <children>
                        <Label text="Label">
                            <GridPane.margin>
                                <Insets />
                            </GridPane.margin>
                        </Label>
                        <Label text="Label" GridPane.rowIndex="1" />
                        <Label text="Label" GridPane.rowIndex="2" />
                        <Label text="Label" GridPane.rowIndex="3" />
                        <TextField GridPane.columnIndex="1" />
                        <TextField GridPane.columnIndex="1" GridPane.rowIndex="1" />
                        <TextField GridPane.columnIndex="1" GridPane.rowIndex="2" />
                        <TextField GridPane.columnIndex="1" GridPane.rowIndex="3" />
                    </children>
                    <BorderPane.margin>
                        <Insets top="15.0" />
                    </BorderPane.margin>
                </GridPane>
            </center>
            <VBox.margin>
                <Insets top="15.0" />
            </VBox.margin>
        </BorderPane>
    </children>
</VBox>

如果您希望它与顶部 and/or 底部一起调整大小,您可以调整边距。

注意:正如我在你的代码中看到的,有很多不可见的对象。我不知道他们是故意在那里还是只是死代码。在我的例子中,我只创建了可见的东西。