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

JavaFX窗口边缘出现1像素白边问题求助

JavaFX游戏引擎窗口右侧1像素白边问题排查与解决

窗口右侧出现1像素白边

在开发JavaFX游戏引擎时,遇到窗口右侧出现异常1像素白边的问题。排查发现Scene的尺寸比Canvas略大(约0.6像素),但Canvas的尺寸设置完全正确。

执行以下代码打印尺寸信息:

System.out.println(sr.getCanvas().getWidth());
System.out.println(GameEngine.scene.getWidth());
System.out.println(GameEngine.stage.getWidth());

System.out.println(sr.getCanvas().getHeight());
System.out.println(GameEngine.scene.getHeight());
System.out.println(GameEngine.stage.getHeight());

输出结果:

1280.0
1280.6259765625
1280.6259765625

720.0
720.102783203125
749.026611328125

相关代码片段

Canvas创建代码:

public void createCanvas() {
    canvas = new Canvas(GameEngine.getConfig().width,GameEngine.getConfig().height);
    gc = canvas.getGraphicsContext2D();
}

窗口创建代码:

private void createWindow() {
    root = new Pane();
    scene = new Scene(root);
    
    stage.setTitle(config.title);
    stage.setScene(scene);
    
    for(Renderer r : GameEngine.renderers) {
        r.createCanvas();
    }
    
    for(Renderer r : renderers) {
        root.getChildren().add(r.getCanvas());
    }
}

已尝试的无效方法

  • 执行stage.hide()后再调用stage.show()
  • 设置stage.setResizable(false)并手动修改Stage宽高
  • 使用以下代码调整Stage尺寸:
    stage.setWidth(scene.getRoot().minWidth(-1));
    stage.setHeight(scene.getRoot().minHeight(-1));
    

可复现问题的示例代码

TestMain.java:

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

TestApp.java:

public class TestApp extends Application {
        
    GraphicsContext gc;
    Stage stage;
    Pane root;
    Scene scene;
    int width;
    int height;
    Canvas canvas;
    
    public TestApp() {}
    
    public void fillCanvas(Paint c) {
        gc.setFill(c);
        gc.fillRect(0, 0, 1280, 720);
    }
    
    public void testLoop() {
        new AnimationTimer() {
            @Override
            public void handle(long nanoTime) {
                fillCanvas(new Color(0.3, 0.3, 0.3, 1));
            }
        }.start();
    }

    @Override
    public void start(Stage arg0) throws Exception {
        Stage stage = new Stage();
        Pane root = new Pane();
        Scene scene = new Scene(root);
        
        int width = 1280;
        int height = 720;
        
        Canvas canvas = new Canvas(width, height);
        gc = canvas.getGraphicsContext2D();
        
        stage.setScene(scene);
        
        root.getChildren().add(canvas);
        stage.show();
        testLoop();
    }
}

解决思路

  1. 强制Scene与Canvas尺寸严格对齐
    在将Canvas添加到根节点后,直接将Scene的尺寸设置为Canvas的精确值,避免布局计算的浮点误差:

    scene.setWidth(canvas.getWidth());
    scene.setHeight(canvas.getHeight());
    

    同时手动修正Stage的尺寸,抵消窗口装饰(标题栏、边框)的影响:

    // 计算窗口装饰的宽度和高度
    double decorWidth = stage.getWidth() - stage.getScene().getWidth();
    double decorHeight = stage.getHeight() - stage.getScene().getHeight();
    // 设置Stage的精确尺寸
    stage.setWidth(canvas.getWidth() + decorWidth);
    stage.setHeight(canvas.getHeight() + decorHeight);
    
  2. 统一背景色掩盖误差
    如果尺寸误差无法完全消除,可以将根节点或Scene的背景色设置为与Canvas的背景色一致,这样微小的白边会被同色背景覆盖:

    // 设置根节点背景
    root.setBackground(new Background(new BackgroundFill(Color.rgb(48, 48, 48), null, null)));
    // 或者直接设置Scene背景
    scene.setFill(Color.rgb(48, 48, 48));
    
  3. 初始化时指定Scene的精确尺寸
    创建Scene时直接传入Canvas的尺寸,避免后续布局调整带来的误差:

    Scene scene = new Scene(root, width, height);
    

    同时确保Canvas的布局坐标为(0,0),没有偏移:

    canvas.setLayoutX(0);
    canvas.setLayoutY(0);
    
  4. 监听尺寸变化动态修正
    添加Stage尺寸变化监听器,每次窗口尺寸变动时强制对齐Scene与Canvas的尺寸:

    stage.widthProperty().addListener((observable, oldValue, newValue) -> {
        double decorWidth = stage.getWidth() - scene.getWidth();
        scene.setWidth(canvas.getWidth());
        stage.setWidth(canvas.getWidth() + decorWidth);
    });
    
    stage.heightProperty().addListener((observable, oldValue, newValue) -> {
        double decorHeight = stage.getHeight() - scene.getHeight();
        scene.setHeight(canvas.getHeight());
        stage.setHeight(canvas.getHeight() + decorHeight);
    });
    

内容的提问来源于stack exchange,提问作者EpicOweo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:15:03