You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX中HBox的setAlignment方法居中失效问题求助

HBox的setAlignment不生效,无法让组件居中显示

我尝试用HBox的setAlignment(Pos.CENTER)让包含按钮、标签和文本框的HBox居中,但方法不生效。操作流程参考了网上资料,实际效果和预期不符,推测遗漏了某些设置。

问题代码片段

HBox edgeBox = new HBox();

edgeBox.getChildren().addAll(addEdge);
edgeBox.getChildren().addAll(vertex1Label, vertex1);
edgeBox.getChildren().addAll(vertex2Label, vertex2);
edgeBox.setSpacing(10);
edgeBox.setAlignment(Pos.CENTER);

效果对比

  • 当前实际效果:HBox内的组件靠左显示,未实现水平居中
  • 期望效果:HBox内的所有按钮、标签和文本框在容器中水平居中

完整代码参考

Project4类

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.io.IOException;

public class Project4 extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        Button addEdge = new Button("Add Edge");
        Button isConnected = new Button("Is Connected?");
        Button hasCycles = new Button("Has Cycles?");
        Button dfs = new Button("Depth First Search");
        Button bfs = new Button("Breadth First Search");

        TextField vertex1 = new TextField();
        vertex1.setPrefWidth(30);
        Label vertex1Label = new Label("Vertex 1  ");

        TextField vertex2 = new TextField();
        vertex2.setPrefWidth(30);
        Label vertex2Label = new Label("Vertex 2  ");

        TextField output = new TextField();
        output.setPrefWidth(400);
        Label outputLabel = new Label();

        HBox edgeBox = new HBox();

        edgeBox.getChildren().addAll(addEdge);
        edgeBox.getChildren().addAll(vertex1Label, vertex1);
        edgeBox.getChildren().addAll(vertex2Label, vertex2);
        edgeBox.setSpacing(10);
        edgeBox.setAlignment(Pos.CENTER);

        MyGraphPane pane = new MyGraphPane();
        pane.setPrefSize(500, 500);
        pane.getChildren().add(edgeBox);
        Scene scene = new Scene(pane);
        stage.setTitle("Project 4");
        stage.setScene(scene);
        stage.show();
    }

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

MyGraphPane类

import javafx.scene.layout.Pane;
import javafx.scene.input.MouseButton;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;

import java.util.List;

public class MyGraphPane extends Pane {
    private MyGraph graph = new MyGraph();

    public MyGraphPane() {
       //this.setPrefSize(500, 500);

        createGraphics();

        //Adds a new vertex to the graph on click
        this.setOnMouseClicked(event -> {
            if(graph.getSize() == 0 && event.getButton() == MouseButton.PRIMARY){
                graph.addVertex(new Vertex(event.getX(), event.getY(), "A"));
            }else if(event.getButton() == MouseButton.PRIMARY)
                graph.addVertex(new Vertex(event.getX(), event.getY(), graph.getLastName()));
            createGraphics();
        });
    }

    private void createGraphics(){
        Circle circle;


        //Draws the vertices
        for(int i = 0; i < graph.getSize(); i++){
            circle = new Circle(graph.getVertex(i).getX(), graph.getVertex(i).getY(), 5);
            this.getChildren().add(circle);
        }

        Line line;

        int i = 0;
        for(List<Integer> list: graph.getEdges()){
            for(Integer J: list){
                line = new Line(graph.getVertex(i).getX(), graph.getVertex(i).getY(),
                        graph.getVertex(J).getX(), graph.getVertex(J).getY());
                if(!this.getChildren().contains(line)){
                    this.getChildren().add(line);
                }
            }
            i++;
        }

    }

    public MyGraph getGraph(){
        return graph;
    }

}

Vertex类

public class Vertex {
    private double x;
    private double y;
    private String name;

    public Vertex(double x, double y, String name) {
        this.x = x;
        this.y = y;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }
}

MyGraph类

package myproject.cmsc315_project4;

import java.util.ArrayList;
import java.util.List;

public class MyGraph{
    protected List<Vertex> vertices = new ArrayList<Vertex>();
    protected List<List<Integer>> edges = new ArrayList<>();

    //Constructor for an empty graph
    public MyGraph(){

    }

    public boolean addVertex(Vertex v){
        if(!vertices.contains(v)){
            vertices.add(v); //adds the new vertex
            edges.add(new ArrayList<>()); //creates a new array list for this vertexes edges
            return true;
        }else
            return false;
    }

    public boolean addEdge(Vertex a, Vertex b){
        if(a.getX() == b.getX() && a.getY() == b.getY()){
            throw new IllegalArgumentException("The vertices are the same");
        }else if(vertices.contains(a) && vertices.contains(b)){
            edges.get(vertices.indexOf(a)).add(vertices.indexOf(b));
            return true;
        }else
            return false;
    }

    //Get the size of the vertices array list
    public int getSize(){
        return vertices.size();
    }

    //Get the name of the last vertex in the list
    public String getLastName(){
        return vertices.get(getSize()-1).getName();
    }

    //Get a specific vertex
    public Vertex getVertex(int i){
        return vertices.get(i);
    }

    public List<List<Integer>> getEdges(){
        return edges;
    }

}

问题原因及解决方案

问题根源

HBox的setAlignment(Pos.CENTER)是控制HBox内部子组件的对齐方式,但你的HBox父容器是Pane,Pane默认不会自动调整子节点的位置,HBox本身在Pane中默认处于左上角,所以即使内部组件居中,整体看起来还是靠左。

解决方法

方法1:绑定HBox的布局位置到Pane中心

通过绑定layoutX和layoutY属性,让HBox始终处于Pane的中心:

MyGraphPane pane = new MyGraphPane();
pane.setPrefSize(500, 500);
pane.getChildren().add(edgeBox);
// 水平居中
edgeBox.layoutXProperty().bind(pane.widthProperty().subtract(edgeBox.widthProperty()).divide(2));
// 垂直居中(可选)
edgeBox.layoutYProperty().bind(pane.heightProperty().subtract(edgeBox.heightProperty()).divide(2));

方法2:更换父容器为支持布局对齐的容器

把MyGraphPane继承的Pane换成BorderPane或VBox这类自带布局功能的容器,比如用BorderPane:

// 修改MyGraphPane继承BorderPane
public class MyGraphPane extends BorderPane {
    // ... 原有代码不变
}

// 在Project4的start方法中设置HBox位置
MyGraphPane pane = new MyGraphPane();
pane.setPrefSize(500, 500);
pane.setTop(edgeBox); // 放在顶部,默认水平居中
// 或者放在中间:pane.setCenter(edgeBox);

方法3:设置HBox的宽度匹配父容器

让HBox的宽度和Pane一致,这样setAlignment就能让内部组件水平居中:

edgeBox.setPrefWidth(500); // 和Pane的prefWidth保持一致
edgeBox.setAlignment(Pos.CENTER);

内容的提问来源于stack exchange,提问作者Steven O'Brien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:02:02