Reputation: 63
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
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
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
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