JavaFX中Box与Border无法居中问题求助
解决JavaFX中Box和Border初始居中问题
问题核心在于boxPane作为Pane容器,默认不会自动适配子节点尺寸,导致StackPane无法正确识别它的大小来完成居中布局。以下是具体修复方案:
修复步骤
1. 给boxPane设置明确尺寸
Pane不会自动包裹子节点,必须手动设置其首选宽高,让StackPane能正确计算居中位置:
Pane boxPane = new Pane(); boxPane.getChildren().addAll(border, grid); // 添加这两行,让boxPane尺寸刚好容纳border和grid boxPane.setPrefWidth(boxSize + borderWidth); boxPane.setPrefHeight(boxSize + borderWidth);
2. 调整子节点位置(优化)
原代码中给border和grid的子节点设置了偏移量,这会导致内容在boxPane内偏移,可直接将位置设为0,让内容填满boxPane:
// 修改border的位置 border.setX(0); border.setY(0); // 修改grid中单元格的位置计算,去掉多余偏移 cell.setX(j * cellSize); cell.setY(i * cellSize);
3. 修正拖拽逻辑(适配新尺寸)
拖拽时的中心点计算需包含border宽度,避免拖拽偏移:
boxPane.setOnMouseDragged(event -> { double newX = event.getSceneX() - (boxSize + borderWidth) / 2; double newY = event.getSceneY() - (boxSize + borderWidth) / 2; boxPane.setTranslateX(newX); boxPane.setTranslateY(newY); });
完整修复代码
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; import javafx.scene.input.ScrollEvent; public class Main extends Application { @Override public void start(Stage primaryStage) { primaryStage.setTitle("JavaFX Movable Box with Border and Grid"); int gridSize = 28; double boxSize = 500.0; // 盒子尺寸 double borderWidth = 2.0; // 边框宽度 double cellSize = boxSize / gridSize; // 单元格尺寸 Pane grid = new Pane(); for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { Rectangle cell = new Rectangle(cellSize, cellSize); cell.setFill(Color.WHITE); cell.setStroke(Color.BLACK); cell.setStrokeWidth(0.5); cell.setX(j * cellSize); cell.setY(i * cellSize); grid.getChildren().add(cell); } } // 创建网格边框 Rectangle border = new Rectangle(boxSize + borderWidth, boxSize + borderWidth); border.setFill(Color.TRANSPARENT); border.setStroke(Color.BLACK); border.setStrokeWidth(borderWidth); border.setX(0); border.setY(0); Pane boxPane = new Pane(); boxPane.getChildren().addAll(border, grid); // 设置boxPane的首选尺寸 boxPane.setPrefWidth(boxSize + borderWidth); boxPane.setPrefHeight(boxSize + borderWidth); StackPane root = new StackPane(); root.getChildren().add(boxPane); Scene scene = new Scene(root, 700, 700); scene.setOnScroll((ScrollEvent event) -> { double zoomFactor = 1.05; double deltaY = event.getDeltaY(); if (deltaY < 0){ zoomFactor = 2 - zoomFactor; } boxPane.setScaleX(boxPane.getScaleX() * zoomFactor); boxPane.setScaleY(boxPane.getScaleY() * zoomFactor); event.consume(); }); boxPane.setOnMouseDragged(event -> { double newX = event.getSceneX() - (boxSize + borderWidth) / 2; double newY = event.getSceneY() - (boxSize + borderWidth) / 2; boxPane.setTranslateX(newX); boxPane.setTranslateY(newY); }); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
内容的提问来源于stack exchange,提问作者KhulZA
相关产品推荐
相关产品推荐

