Search code examples
javajavafxcanvasline

Integrating both canvas and pane with Line objects in JavaFX


Disclaimer: I am using Java and Javafx 11. Just putting it out there :)

I am in the process of trying to create an Interpreter for Logo, but have run into a roadblock. You see, I defaulted to using a canvas to display all the things I needed as that is fitting for what I am doing. However, I did not account for the fact that my Turtle needed to move.

private void drawTurtle() 
{
    vertices[0] = new Vector2(position.x, position.y + 15); // The three points that make the triangle that is the turtle
    vertices[1] = new Vector2(position.x - 15, position.y);
    vertices[2] = new Vector2(position.x + 15, position.y);
    
    vertices[1] = Renderer.rotatePoint(vertices[1], position, rotation); // applying rotation to vertices
    vertices[2] = Renderer.rotatePoint(vertices[2], position, rotation);
    vertices[0] = Renderer.rotatePoint(vertices[0], position, rotation);
    
    Renderer.drawLine(vertices[2], vertices[1], currentPen); // drawing the vertices
    Renderer.drawLine(vertices[2], vertices[0], currentPen);
    Renderer.drawLine(vertices[1], vertices[0], currentPen);
}

enter image description here Trails left due to rotating the turtle in realtime Trails left due to rotating the turtle in realtime.

In order to achieve this without leaving "trails", I tried to erase the existing turtle by drawing with a white pen over it. That gave me... weird results.

enter image description here This is after rotating the turtle 360 degrees.

Then I came across a post here on SO talking about how I should use a Line object on a Pane if I wanted to move stuff. And well, I tried combining it with a canvas to make a CanvasPane:

public class CanvasPane extends Pane
{
    public final Canvas canvas;

    public CanvasPane(double width, double height)
    {
        setWidth(width);
        setHeight(height);
        canvas = new Canvas(width, height);
        getChildren().add(canvas);

        canvas.widthProperty().bind(this.widthProperty()); // Change this so this canvas does not scale with the pane, and its size is constant.
        canvas.heightProperty().bind(this.heightProperty());
    }
}

And added line objects to this so I can then edit their start and end values to make the turtle move, but I got nothing out of it, no line to show, and I am quite confused and don't know what to do. Nothing on the great internet helped my either, so I am now asking this question to see if anyone has ideas on how I can move my turtle flawlessly. And no, I can't use clearRect()

TLDR: My turtle leaves trails when moving on a canvas, and using Line and Pane doesn't work, and I can't use clearRect() on my canvas. Help!


Solution

  • Use one Pane to hold both the Canvas Node and your "turtle" Node.

        Canvas canvas = new Canvas(640, 480);
        Shape turtle = new Polygon(); // fill in the points
        Pane p = new Pane(canvas, turtle);
    

    Now you can control the position of the turtle node by either setting the layout coordinates or applying a translation. As it was added last, it will be drawn over the Canvas. (You could also use a StackPane to make that layering more explicit.)