JavaFX窗口边缘出现1像素白边问题求助
JavaFX游戏引擎窗口右侧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(); } }
解决思路
强制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);统一背景色掩盖误差
如果尺寸误差无法完全消除,可以将根节点或Scene的背景色设置为与Canvas的背景色一致,这样微小的白边会被同色背景覆盖:// 设置根节点背景 root.setBackground(new Background(new BackgroundFill(Color.rgb(48, 48, 48), null, null))); // 或者直接设置Scene背景 scene.setFill(Color.rgb(48, 48, 48));初始化时指定Scene的精确尺寸
创建Scene时直接传入Canvas的尺寸,避免后续布局调整带来的误差:Scene scene = new Scene(root, width, height);同时确保Canvas的布局坐标为(0,0),没有偏移:
canvas.setLayoutX(0); canvas.setLayoutY(0);监听尺寸变化动态修正
添加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
相关产品推荐
相关产品推荐

