2

Currently I have the following problem: I would like to draw a straight angled line in JavaFX Canvas like so (Recalling from memory so method names might not be accurate):

Canvas canvas = new Canvas(500, 600);

GraphicsContext gc = canvas.getGraphicsContext2D();

gc.setStroke(Color.GREEN);

gc.setLineWidth(5.0);

gc.strokeLine(10, 10, 200, 200);

Now when I want to clear this line, I could obviously clear the entire Canvas using gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); but that is clearing the entire canvas including other lines and points I may want to keep. Say, for example I have created a new point after the line: gc.strokeOval(50, 20, 5, 5); How would I in one step clear only the line and not the point?

Having googled the problem already, I didn't find anything about exactly this. I am kind of expecting it just doesn't work but maybe some of you might find a workaround for this.

I already tried searching for another method in GraphicsContext but were unsuccessful.

nick16384
  • 41
  • 5
  • What does it actually mean to clear the line in this case? Once you have cleared it, what is displayed in the place the line used to be? – jewelsea Jul 28 '23 at 09:08
  • [clearRect](https://openjfx.io/javadoc/17/javafx.graphics/javafx/scene/canvas/GraphicsContext.html#clearRect(double,double,double,double)) “Clears a portion of the canvas with a transparent color value.” -> is that what you want to do? Make the pixels where the line was transparent? – jewelsea Jul 28 '23 at 09:13
  • You could use a layer system like in the [tutorial](https://docs.oracle.com/javase/8/javafx/graphics-tutorial/canvas.htm). With each element you add a new layer, then hide or remove the layer you don’t want to show. Maybe that doesn’t meet your “efficient” criteria though. Similarly you could draw the line over the canvas using the scene graph, then it is easy to remove it from the scene graph when you want to. – jewelsea Jul 28 '23 at 09:23
  • In this case, "clearing" means replacing the line pixels with whatever background color. I am actually planning to make a visual "radar / sonar" with a line sweeping from left to right and back, and in between I want to draw the scanned distance points connected with lines. I could redraw those every time, but that is inefficient. – nick16384 Jul 28 '23 at 09:26
  • Then just set the stroke to the background color and repaint the line. Or did I miss something? – jewelsea Jul 28 '23 at 09:43
  • I have thought of stroking the background color and repainting another line, but I thought that introduces memory problems, because the lines stack on top of each other. Am I right with this or is it rather a stupid assumption? And also: Thanks for your quick responses! – nick16384 Jul 28 '23 at 09:48
  • *”I thought that introduces memory problems, because the lines stack on top of each other”* -> No. a canvas is not like the scene graph. Elements are not retained in memory. Instead the commands are buffered to a queue, and each pulse (up to 60 times a second) the command buffer is emptied by executing the commands and updating the pixel buffer backing the canvas, which is then rendered as a texture to the graphics device. So you can draw on it as much as you want. It only retains a constant size memory array for the pixels in the canvas over the long term. – jewelsea Jul 28 '23 at 10:33
  • 1
    You may want to consider abandoning the `Canvas` approach and instead use the scene graph. Especially if you're going to have moving components (e.g., the line). – Slaw Jul 28 '23 at 18:26

1 Answers1

2

Based on the comments on the question, this may be the answer:

gc.setStroke(backgroundColor);
gc.strokeLine(10, 10, 200, 200);
gc.setStroke(Color.GREEN)

This clears the line by drawing the same line in the backgroundColor over it, effectively removing it.

nick16384
  • 41
  • 5