Reputation: 33
I am drawing inside JavaFx Canvas the program draw many different shapes and one of them represent a position marker(Oval) in some situation its position must be updated every 1 second and this is OK to remove several traces of marker I have to redraw again and this slow the program the question how can I redraw only the current marker removing its traces without drawing all shapes?? much like swing repaint() .
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
public class DrawChart {
private Timeline timelinePosition;
private Canvas canvas;
private GraphicsContex graphicsContex;
public void start() {
canvas = new Canvas();
graphicsContex = canvas.getGraphicsContext2D();
drawManyShapes();
drawPositionMarker();
someStateMonitor();
}
public void drawManyShapes() {
draw many shapes .......
}
public void drawPositionMarker() {
EventHandler eventHandler = new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
graphicsContex.strokeOval(posi_x , posi_y, width , hight );
}
};
Duration duration = Duration.millis(1000);
timelinePosition = new Timeline();
timelinePosition.setDelay(duration);
timelinePosition.setCycleCount(Timeline.INDEFINITE);
KeyFrame keyPosition = new KeyFrame(duration, drawPosition , null, null);
timelinePosition.getKeyFrames().add(keyPosition);
}
public void someStateMonitor() {
if(state == true) timelinePosition.play();
if(state == false) timelinePosition.stop();
}
}
Upvotes: 3
Views: 9520
Reputation: 697
I have encountered this issue as well (for me rectangle) and I made a rectangle class, you could to the same but with ovals. The example is just to give you a idea
class Rectangle {
//x position
int x;
//y position
int y;
//size for width
int xSize;
//size for height
int ySize;
//to draw on the canvas
GraphicsContext graphics;
//used to create a rectangle object
public Rectangle(GraphicsContext graphics, int x, int y, int xSize, int ySize) {
//sets fields used for the rectangle
this.x = x;
this.y = y;
this.xSize = xSize;
this.ySize = ySize;
this.graphics = graphics;
graphics.fillRect(x, y, xSize, ySize);
}
//used to get rid of rectangles
public void delete(Rectangle rectangle) {
//erase the rectangle
(rectangle.graphics).clearRect(rectangle.x, rectangle.y, rectangle.xSize, rectangle.ySize);
//erase its fields
rectangle.x = -1;
rectangle.y = -1;
rectangle.xSize = -1;
rectangle.ySize = -1;
}
//will redraw the rectangle
public void reDraw(Rectangle rectangle) {
(rectangle.graphics).fillRect(rectangle.x, rectangle.y, rectangle.xSize, rectangle.ySize);
}
//will move the rectangle
public void move(Rectangle rectangle, int x, int y) {
(rectangle.graphics).clearRect(rectangle.x, rectangle.y, rectangle.xSize+1, rectangle.ySize+1);
(rectangle.graphics).fillRect(x, y, rectangle.xSize, rectangle.ySize);
}
//redifine the fields
this.x = x;
this.y = y; } }
You could add other fields as well.
Upvotes: 0
Reputation: 10969
You can add layers of canvases. Or you can save a rectangle under your shape and redraw that after.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class LayeredCanvas extends Application {
@Override
public void start(Stage primaryStage) {
Canvas layer1 = new Canvas(700, 300);
Canvas layer2 = new Canvas(700, 300);
GraphicsContext gc1 = layer1.getGraphicsContext2D();
GraphicsContext gc2 = layer2.getGraphicsContext2D();
gc1.setFill(Color.GREEN);
gc1.setFont(new Font("Comic sans MS", 100));
gc1.fillText("BACKGROUND", 0, 100);
gc1.fillText("LAYER", 0, 200);
gc1.setFont(new Font(30));
gc1.setFill(Color.RED);
gc1.fillText("Hold a key", 0, 270);
gc2.setFill(Color.BLUE);
Pane root = new Pane(layer1, layer2);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
scene.setOnKeyPressed((evt) -> {
gc2.clearRect(0, 0, layer2.getWidth(), layer2.getHeight());
gc2.fillOval(Math.random() * layer2.getWidth(), Math.random() * layer2.getHeight(), 20, 30);
});
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 2