[英]FXML BorderPane centered inside another BorderPane
所以,我一直試圖將一個 BorderPane 放在另一個 BorderPane(中心部分)中,但到目前為止還沒有成功。
我已經嘗試過(都在從 FXML 和父場景加載的窗格中):
SetPadding
setMargin
AnchorPane
並設置頂部、底部、左側和右側錨點Regions
(無效且在調整舞台大小時不起作用)如果我使用窗格或節點以外的任何東西來加載 FXML
Pane pane = loader.load();
像 HBox、VBox、AnchorPane 或 Group 一樣,FXML 不會加載;
當前布局:
我正在尋找的結果(大致)
這個想法是即使當我調整窗口大小時,FXML 布局也會保持在 MainBorderPane 的中心;
紅色邊框:Stage -> Scene -> BorderPane 藍色邊框:BorderPane 在showNewScene(FXMLPath)
方法中通過 FXML 加載
(仿真源代碼:包示例)
主程序
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
private static BorderPane mainBorderPane;
private static Scene mainScene;
private static MenuBar mainMenuBar;
private static Stage mainStage;
private static Menu mainMenuFile;
private static MenuItem mainItemMenuLock;
private static MenuItem mainItemMenuClose;
private static Menu mainMenuHelp;
private static MenuItem mainItemMenuSupport;
public static BorderPane getMainBorderPane() {
if (mainBorderPane == null) {
mainBorderPane = new BorderPane();
}
return mainBorderPane;
}
public static Scene getMainScene() {
if (mainScene == null) {
mainScene = new Scene(getMainBorderPane(), 800, 600);
}
return mainScene;
}
public static MenuBar getMainMenuBar() {
if (mainMenuBar == null) {
mainMenuBar = new MenuBar();
mainMenuFile = new Menu("File");
mainItemMenuLock = new MenuItem("Lock Screen");
mainItemMenuClose = new MenuItem("Close");
mainMenuFile.getItems().addAll(mainItemMenuLock, mainItemMenuClose);
mainMenuHelp = new Menu("Help");
mainItemMenuSupport = new MenuItem("Support");
mainMenuHelp.getItems().addAll(mainItemMenuSupport);
mainMenuBar.getMenus().addAll(mainMenuFile, mainMenuHelp);
}
return mainMenuBar;
}
public static Stage getMainStage() {
if (mainStage == null) {
getMainBorderPane().setTop(getMainMenuBar());
mainStage = new Stage(StageStyle.DECORATED);
}
return mainStage;
}
public static void main(String[] args) {
launch(args);
}
@Override
public void init() {
//
}
@Override
public void start(final Stage initStage) throws Exception{
UtilMethods.showNewScene("login.fxml");
}
}
實用方法.java
package sample;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.layout.Pane;
public class UtilMethods {
public static void showNewScene(String fxmlPath) {
try {
FXMLLoader loader = new FXMLLoader(UtilMethods.class.getResource(fxmlPath));
Pane pane = loader.load();
Main.getMainBorderPane().setCenter(pane);
Main.getMainBorderPane().setAlignment(pane, Pos.CENTER);
Main.getMainStage().setScene(Main.getMainScene());
Main.getMainStage().setAlwaysOnTop(false);
Main.getMainStage().setResizable(true);
Main.getMainStage().show();
}catch (java.io.IOException e){
System.out.println("Error loading screen" + e.getMessage());
}
}
}
登錄控制器.java
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
public class LoginController {
@FXML private TextField userIdField;
@FXML private PasswordField passwordField;
public void initialize(){
//
}
@FXML
private void login(ActionEvent event) {
System.out.println("login");
}
@FXML
private void cancel(){
userIdField.clear();
passwordField.clear();
userIdField.requestFocus();
}
@FXML
private void registerNew(ActionEvent event) throws Exception{
System.out.println("register new");
}
}
登錄文件
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane xmlns:fx="http://javafx.com/fxml/1" hgap="10" vgap="10"
fx:controller="sample.LoginController" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
<padding>
<Insets top="10" right="10" bottom="10" left="10"/>
</padding>
<children>
<Label text="Username:" GridPane.columnIndex="0"
GridPane.rowIndex="0" GridPane.halignment="RIGHT" />
<Label text="Password:" GridPane.columnIndex="0"
GridPane.rowIndex="1" GridPane.halignment="RIGHT" />
<Label text="Database connection status:" GridPane.columnIndex="0"
GridPane.rowIndex="2" GridPane.halignment="RIGHT" />
<Label fx:id="labelDBStatus" text="..." GridPane.columnIndex="1"
GridPane.rowIndex="2" GridPane.halignment="RIGHT" />
<TextField fx:id="userIdField" GridPane.columnIndex="1" GridPane.rowIndex="0"
promptText="User ID" styleClass="text-field"/>
<PasswordField fx:id="passwordField" GridPane.columnIndex="1" GridPane.rowIndex="1"
promptText="Password" styleClass="text-field"/>
<HBox GridPane.columnIndex="0" GridPane.rowIndex="3"
GridPane.columnSpan="2" alignment="CENTER" spacing="10">
<children>
<Button fx:id="btnLogin" text="Login" onAction="#login" />
<Button fx:id="btnCancel" text="Cancel" onAction="#cancel"/>
<Button fx:id="btnRegister" text="Register" onAction="#registerNew"/>
</children>
</HBox>
</children>
</GridPane>
你得到這個的原因是,如果某個區域不包含子組件,該區域可能被其他區域占用。 在這種情況下,由於您的 GridPane 是 BorderPane 中唯一的組件,因此它會自動轉到左上角。 為避免這種情況,您必須在邊框窗格中使用其他組件,或者考慮使用 VBox(而不是 gridPane)之類的東西,它繼承其父尺寸,以便您的屏幕居中。
正如 James_D 在評論中所說:
向 FXML 中的 GridPane 根元素添加一個alignment="CENTER"屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.