JavaFX 面板内部的面板自动调整大小

49
我有一个JavaFX应用程序,只有一个FXML文件。在这个文件中,我有一个AnchorPane,里面有一个StackPane。以下是屏幕截图:

my panel inside panel application

当我启动这个应用程序时,我希望StackPane能够自动调整大小并与AnchorPane一起自适应大小。因此,StackPane将自动获取当前可用的宽度和高度。在我调整应用程序大小的时候,AnchorPane会自动调整大小,但是StackPane仍然保持原来的大小。
我该如何自动调整StackPane的大小,并使其完全延伸到其父面板内?
我的代码:

Main.java

package app;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

  public static void main(String[] args) {
      Application.launch(args);
  }

  @Override
  public void start(Stage stage) throws Exception {
      Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
      Scene scene = new Scene(root,800,600);
      scene.getStylesheets().add(this.getClass().getResource("/app/style1.css").toExternalForm());
      stage.setScene(scene);
      stage.show();
  }
}

MainController.java

package app;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;

public class MainController implements Initializable {

   @FXML
   private AnchorPane anchorPane;
   @FXML
   private StackPane stackPane;

   @Override
   public void initialize(URL url, ResourceBundle rb) {
     stackPane.setPrefSize(anchorPane.getPrefWidth(), anchorPane.getPrefHeight()); //didn't work
   }    
}

Main.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane fx:id="anchorPane" xmlns:fx="http://javafx.com/fxml" fx:controller="app.MainController">
    <StackPane fx:id="stackPane" ></StackPane>
</AnchorPane>

style1.css

#anchorPane { 
    -fx-border-width: 2px;
    -fx-border-color: chartreuse;
}
#stackPane {
    -fx-border-width: 2px;
    -fx-border-color: red;

    /* didn't work */
   -fx-hgap: 100%;
   -fx-vgap: 100%;
}
6个回答

83

在搜索和测试了几个小时之后,终于在发布问题后找到了答案!

您可以使用"AnchorPane.topAnchor,AnchorPane.bottomAnchor,AnchorPane.leftAnchor,AnchorPane.rightAnchor" fxml命令并将值设置为"0.0"来适应/拉伸/对齐 AnchorPane 中的子元素。因此,这些命令告诉子元素在调整大小时跟随其父元素。

我的更新代码 Main.fxml

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

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

<AnchorPane fx:id="anchorPane" xmlns:fx="http://javafx.com/fxml" fx:controller="app.MainController">
    <!--<StackPane fx:id="stackPane" ></StackPane>--> <!-- replace with the following -->
    <StackPane fx:id="stackPane" AnchorPane.topAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" ></StackPane>
</AnchorPane>

这是结果:

enter image description here

关于API文档:http://docs.oracle.com/javafx/2/api/javafx/scene/layout/AnchorPane.html


3
你能接受这个答案吗?这会让我们知道这个问题有解决方案。不过,找到这个真不容易,很棒! - blo0p3r
2
@blo0p3r 我会的,但现在系统说“您需要等待2天才能接受自己的答案”;) 希望还有其他更多的建议。 - Korki Korkig
你好。当添加一个按钮时,例如:<AnchorPane fx:id="mainContent" ...> <StackPane fx:id="subPane" AnchorPane.topAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" > Button fx:id="button" layoutX="172.0" layoutY="195.0" onAction="#ingresarLogin" prefHeight="35.0" prefWidth="87.0" text="Ingresar" /> </StackPane> </AnchorPane> 这样是正确的吗?谢谢。 - Marco R
这也适用于其他控件,不仅仅是面板。我刚在TabbedPane、AnchorPane和TreeView上使用了它,它们都可以自动拉伸以适应大小。非常有帮助。 - Andrew Grothe
如果您希望锚点为0,为什么要在AnchorPane内保留StackPane? - cubuspl42
@cubuspl42 想象一下,您想在底部(绿色区域内)放置类似按钮的东西,同时仍希望面板(红色区域)沿着空白区域伸展......我不记得为什么了,但它很有用,我仍然认为如此。 - Korki Korkig

17

我正在使用SceneBuilder设计GUI,尝试让主容器适应任何窗口大小。它应该始终是100%宽。

这就是在SceneBuilder中设置这些值的地方:

AnchorPane Constraints in SceneBuilder

切换虚线/红线实际上只会添加/删除Korki在他的解决方案中发布的属性(如AnchorPane.topAnchor等)。


这会生成什么FXML代码?我想看看。 - Andrew S
1
你为什么不自己打开SceneBuilder看看呢?这个过程真的只需要不到20秒钟。 - specializt

10

还可以查看这里

@FXML
private void mnuUserLevel_onClick(ActionEvent event) {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("DBedit.fxml"));
    loader.setController(new DBeditEntityUserlevel());

    try {
           Node n = (Node)loader.load();
           AnchorPane.setTopAnchor(n, 0.0);
           AnchorPane.setRightAnchor(n, 0.0);
           AnchorPane.setLeftAnchor(n, 0.0);
           AnchorPane.setBottomAnchor(n, 0.0);
           mainContent.getChildren().setAll(n);
    } catch (IOException e){
           System.out.println(e.getMessage());
    }
}

该场景是将子fxml加载到父AnchorPane中。要使子级根据其父级自动伸展,请使用AnChorPane.setxxxAnchor命令。


1

不需要放弃。

只需选择窗格右键单击,然后选择适应父级

它会自动调整窗格大小以适应锚点窗格的大小。


0
如果您正在使用Scene Builder,您将在右侧看到一个手风琴面板,通常有三个选项(“属性”,“布局”和“代码”)。在第二个选项卡(“布局”)中,您将看到一个名为“[parent layout] Constraints”的选项(在您的情况下是“AnchorPane Constrainsts”)。
您应该在代表父布局的元素的四个边缘上放置“0”。

0

这很简单,因为您正在使用FXMLBuilder

只需按照以下简单步骤操作:

  1. 将FXML文件打开到FXMLBuilder中。
  2. 选择堆栈面板。
  3. 打开布局选项卡[FXMLBuilder的左侧选项卡]。
  4. 设置边缘值,以便在舞台调整大小期间计算窗格大小,如TOP、LEFT、RIGHT、BOTTOM。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接