Suppose you have an app that displays user graphic (some kind of image) then you want to allow the user to draw some lines on this image. I have the following questions regarding such situation:
How would you accomplish that? How would you get pixel coordinates for the image from the user drag events? How would you update the image in real time?
I will give you an example of the exact opposite [erasing the Image on JavaFX] which I suppose will be enough as a starter point for you:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class EraseImageonCanvas extends Application {
private Pane root = new Pane();
private void setCanvas(Canvas canvas, Image img) {
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.drawImage(img, 0, 0,canvas.getWidth(), canvas.getHeight());
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Erasing the Image");
Rectangle rect = new Rectangle(400, 400);
drawBackground(rect);
root.getChildren().add(rect);
final Canvas canvas = new Canvas(200, 200);
canvas.setTranslateX(100);
canvas.setTranslateY(100);
//For local images use
//image = new Image(getClass().getResource(#Path#).openStream());
final Image image = new Image(
"http://kyllo.com.br/wp-content/uploads/2013/12/Faroeste-Cabloco.jpg"
);
setCanvas(canvas,image);
final GraphicsContext gc = canvas.getGraphicsContext2D();
// Clear away portions as the user drags the mouse
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
gc.clearRect(e.getX() - 2, e.getY() - 2, 5, 5);
}
});
// Reset the Canvas when the user double-clicks
canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
if (t.getClickCount() >1) {
setCanvas(canvas, image);
}
}
});
// Add the Canvas to the Scene, and show the Stage
root.getChildren().add(canvas);
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
//Draws the background with a RadialGradient
private void drawBackground(Rectangle rect) {
rect.setFill(new LinearGradient(0, 0, 1, 1, true,
CycleMethod.REFLECT,
new Stop(0, Color.RED),
new Stop(1, Color.YELLOW)));
}
public static void main(String[] args) {
launch(args);
}
}
Download it on gist
this Canvas tutorial by Oracle shows exactly what you want to accomplish in the "Interacting with the User" section.
It shows how you can add an EventHandler to the Canvas to handle MouseEvent such as MouseEvent.MOUSE_DRAGGED
. The GraphicsContext is then used to get the x and y coordinates and draw on the canvas.
In order to use the Canvas outside the main Application class, you'd declare the Canvas in your .fxml file as such:
<BorderPane fx:controller="controllers.MyController"
xmlns:fx="http://javafx.com/fxml">
<Canvas fx:id="drawArea" height="..." width="..."/>
</BorderPane>
Then, on your MyController class:
public class MyController implements Initializable {
@FXML
private Canvas drawArea;
private GraphicsContext gc;
@Override
public void initialize(URL location, ResourceBundle resources) {
gc = drawArea.getGraphicsContext2D();
// Java 8 syntax, beware!
drawArea.setOnMouseDragged(event -> gc.fillRect(event.getX(), event.getY(), 5, 5));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With