EpicOweo
EpicOweo

Reputation: 63

White line appearing on the edge of JavaFX window

I'm making a game engine with JavaFX and I've come across this problem that I'm struggling to fix. There is a one pixel wide white line on the right side of my window that shouldn't be there:

The problem appears to be caused by my Scene being ~0.6 pixels too large, even though my canvas is the correct size. However, I don't know what to do to fix it.

Running the following lines gives me the following outputs, respectively:

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

Creating the canvas:

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

Creating the window:

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());
    }
}

I've been looking all over trying the couple things I could find but they haven't worked, including:

stage.setWidth(scene.getRoot().minWidth(-1));
stage.setHeight(scene.getRoot().minHeight(-1));

Any ideas? I'm willing to give more information if needed, I'm apparently not great at giving detailed enough answers so hopefully this was alright. Thanks!

EDIT: Here's a reproducible example of my problem (at least on my device): TestMain.class

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

TestApp.class

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();
    }
}

If anything else is needed please let me know!

Upvotes: 4

Views: 127

Answers (3)

EpicOweo
EpicOweo

Reputation: 63

UPDATE: I figured out what actually works! Making the canvas bigger just worsened the problem, so after some playing around I bound the maxWidthProperty/maxHeightProperty to the Canvas' width/height properties minus one.

stage.maxWidthProperty().bind(canvas.widthProperty().subtract(1));
stage.maxHeightProperty().bind(canvas.heightProperty().subtract(1));

Since this seems to mainly be a me problem, I just included these as a seperate patch function in my code in case someone using my engine also has the issue.

Upvotes: 0

Francis Fajardo
Francis Fajardo

Reputation: 322

I can't reproduce this either on Windows 10/Ubuntu 22.04 (both running JDK/JavaFX 20). If you're fine with not letting the user resize the game window, try the following code, which should prevent resizing* of the window/stage and sets an initial size for the scene.

stage.setResizable(false);
Scene scene = new Scene(root, 1280, 720);

* Do note that there are a few WMs that don't respect this setting.

Upvotes: 0

EpicOweo
EpicOweo

Reputation: 63

I didn't find the source of the problem but I found a workaround. Basically the idea is to just use scene.setFill() to clear the screen. When I do that, it clears the entire screen even though the Scene's size is a pixel off. I also will probably still clear the canvas every frame as well to make sure nothing weird happens though.

EDIT: Also helps to make the canvas one pixel bigger so that whatever you're drawing spans the entire window.

Upvotes: 0

Related Questions