Reputation: 107
So, I know how to do free hand lines but I want a straight line so when a user clicks a point to the point where the user releases the mouse and when the user drags the mouse the end point should move with the mouse i.e similar to drawing straight lines in the paint app.
Presently working with this code:
public class JavaFX_DrawOnCanvas extends Application {
@Override
public void start(Stage primaryStage) {
Canvas canvas = new Canvas(400, 400);
final GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
initDraw(graphicsContext);
canvas.addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
graphicsContext.beginPath();
graphicsContext.moveTo(event.getX(), event.getY());
graphicsContext.stroke();
}
});
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED,
new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
graphicsContext.lineTo(event.getX(), event.getY());
graphicsContext.stroke();
}
});
canvas.addEventHandler(MouseEvent.MOUSE_RELEASED,
new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
}
});
StackPane root = new StackPane();
root.getChildren().add(canvas);
Scene scene = new Scene(root, 400, 400);
primaryStage.setTitle("java-buddy.blogspot.com");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private void initDraw(GraphicsContext gc){
double canvasWidth = gc.getCanvas().getWidth();
double canvasHeight = gc.getCanvas().getHeight();
gc.setFill(Color.LIGHTGRAY);
gc.setStroke(Color.BLACK);
gc.setLineWidth(5);
gc.fill();
gc.strokeRect(
0, //x of the upper left corner
0, //y of the upper left corner
canvasWidth, //width of the rectangle
canvasHeight); //height of the rectangle
gc.setFill(Color.RED);
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
}
}
How to modify the mouse drag event to draw straight lines and not free hand?
Upvotes: 2
Views: 5141
Reputation: 3885
Generally, I agree with comments - it is easier to do this using Line. But with canvas you can achieve the same like so:
public class JavaFX_DrawOnCanvas extends Application {
private Pair<Double, Double> initialTouch;
private Canvas layer = new Canvas();
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Canvas canvas = new Canvas(400, 400);
final GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
initDraw(graphicsContext);
canvas.addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
Canvas newLayer = new Canvas(400, 400);
GraphicsContext context = newLayer.getGraphicsContext2D();
initDraw(context);
layer = newLayer;
root.getChildren().add(0, newLayer);
initialTouch = new Pair<>(event.getSceneX(), event.getSceneY());
}
});
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED,
new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
GraphicsContext context = layer.getGraphicsContext2D();
context.clearRect(0, 0, layer.getWidth(), layer.getHeight());
context.strokeLine(initialTouch.getKey(), initialTouch.getValue(), event.getSceneX(), event.getSceneY());
}
});
root.getChildren().add(canvas);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private void initDraw(GraphicsContext gc){
double canvasWidth = gc.getCanvas().getWidth();
double canvasHeight = gc.getCanvas().getHeight();
gc.setFill(Color.LIGHTGRAY);
gc.setStroke(Color.BLACK);
gc.setLineWidth(5);
gc.fill();
gc.strokeRect(
0, //x of the upper left corner
0, //y of the upper left corner
canvasWidth, //width of the rectangle
canvasHeight); //height of the rectangle
gc.setFill(Color.RED);
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
}
public static void main(String[] args) {
launch(args);
}
}
So, basically you need to create separate layer for each new line and use strokeLine method. Note, that newly added layer must be added at the 0 index to the root children because otherwise event handler of the main canvas would stop process events.
Upvotes: 4