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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:50:35