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
相关产品推荐
相关产品推荐

