1

Actually I am making an application which allows user to crop an image an then gives functionality of free-hand drawing and to also to draw different shapes. I have achieved functionality of cropping and drawing shapes like line etc. But I am facing some problems in free-hand drawing.

I have added my image on "HBox" and cropped that image through "Rectangle" in JavaFX class which is added on "Group". And all these are added on "Pane" class. Now for free-hand drawing, I am using "Canvas". Where to add canvas, whether on "HBox" or "Group" or "Pane" class. And Canvas is only initialized on clicking pencil button. I have added single functions for Mouse-Events and applied if-checks for different functionalities in those functions. basically how to draw pencil on image or how to add lineTo on group. Can someone please help me in solving my problem??
`

    package application;

import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.imageio.ImageIO;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.Rectangle;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

public class Main extends Application {

    int dragStatus = 0;
    double startingPointX;
    double startingPointY;
    double currentEndingPointX;
    double currentEndingPointY;
    BufferedImage bufferedImage;
    Robot robot;
    ImageView imageView;
    Button  pencilBtn;
    Image image;
    Pane rootPane;
    HBox pictureRegion;
    Scene scene;
    Rectangle croppedArea;
    Canvas canvas;
    GraphicsContext gc;
    WritableImage writableImage;
    Group group = new Group();
    Line line;
    LineTo lineTo;
    String shape;
    Boolean canvasAdded;

    @Override
    public void start(Stage primaryStage) {
        try {
            int sleepTime = 120;
            Thread.sleep(sleepTime);
            pencilBtn = createButton("save.png");
            pictureRegion = new HBox();
            rootPane = new Pane();
            scene = new Scene(rootPane);
            robot = new Robot();
            java.awt.Rectangle capture = new java.awt.Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
            bufferedImage = robot.createScreenCapture(capture);
            image = ConvertBufferedToJavaFXImage.convertToFxImage(bufferedImage);
            pencilBtn.setOnAction(e -> geometrySelection("pencil"));
            croppedArea = new Rectangle();
            if(canvas != null) {
                canvas.setOnMousePressed(e -> onMousePressed(e));
                canvas.setOnMousePressed(e -> onMouseDragged(e));
            }
            imageView = new ImageView(image);
            scene.setOnMouseEntered(e -> onMouseEntered(e, "scene"));
            scene.setOnMousePressed(e -> onMousePressed(e));
            scene.setOnMouseReleased(e -> onMouseReleased(e));
            scene.setOnMouseDragged(e -> onMouseDragged(e));
            pictureRegion.getChildren().add(imageView);
            rootPane.getChildren().add(pictureRegion);
            rootPane.getChildren().add(group);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setMaximized(true);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void onMouseEntered(MouseEvent ev, String nodeType) {
        if (nodeType == "scene") {
            scene.setCursor(Cursor.CROSSHAIR);
        } else if (nodeType == "croppedArea") {
            croppedArea.setCursor(Cursor.TEXT);
            //croppedArea.setOnMousePressed(e -> onMousePressed(e));
        } else if (nodeType == "btn") {
            pencilBtn.setCursor(Cursor.HAND);
        }
    }

    public void onMousePressed(MouseEvent event) {
        if ((startingPointX < event.getX() && event.getX() < currentEndingPointX)
                && (startingPointY < event.getY() && event.getY() < currentEndingPointY)) {
 if(shape == "pencil") {
                lineTo = new LineTo();
                System.out.println("lineTo1");
                gc.beginPath();
                gc.lineTo(event.getX(), event.getY());
                gc.stroke();
            }
        } else {
            shape = "croppedArea";
            rootPane.getChildren().remove(canvas);
            group.getChildren().clear();
            startingPointX = event.getX();
            startingPointY = event.getY();
            group.getChildren().add(croppedArea);
        }
    }

    public void onMouseDragged(MouseEvent event) {
        dragStatus = 1;
        if (dragStatus == 1) {
//          if((startingPointX < event.getX() && event.getX() < currentEndingPointX)
//                  && (startingPointY < event.getY() && event.getY() < currentEndingPointY)) {
             if(shape == "pencil") {

                System.out.println("lineTo1");
                gc.lineTo(event.getX(), event.getY());
                gc.stroke();
            }
            else {
                currentEndingPointX = event.getX();
                currentEndingPointY = event.getY();
                rootPane.getChildren().remove(pencilBtn);
                croppedArea.setFill(Color.TRANSPARENT);
                croppedArea.setStroke(Color.BLACK);
                croppedArea.setOnMouseEntered(e -> onMouseEntered(e, "croppedArea"));
                adjustRectangleProperties(startingPointX, startingPointY, currentEndingPointX, currentEndingPointY,
                        croppedArea);
            }
        }
    }

    public void geometrySelection(String tempShape) {
        if(tempShape == "pencil") {
            shape = "pencil";
            canvas = new Canvas();
            gc = canvas.getGraphicsContext2D();
            //gc.setFill(Color.LIGHTGRAY);
            gc.setStroke(Color.BLACK);
            gc.setLineWidth(5);
            canvas.setLayoutX(startingPointX);
            canvas.setLayoutY(startingPointY);
            canvas.setWidth(croppedArea.getWidth());
            canvas.setHeight(croppedArea.getHeight());
            System.out.println("canvasAdded");
            group.getChildren().add(canvas);
        }
    }

    public void onMouseReleased(MouseEvent event) {
        if(dragStatus == 1) {
             if(shape == "croppedArea") {
                if (croppedArea.getHeight() > 0 && croppedArea.getWidth() > 0) {
                    pencilBtn.setLayoutX(Math.max(startingPointX, currentEndingPointX) + 5);
                    pencilBtn.setLayoutY(Math.max(startingPointY, currentEndingPointY) - 120);
                    rootPane.getChildren().add(pencilBtn);
                    dragStatus = 0;
                }
            }
            bufferedImage = robot.createScreenCapture(new java.awt.Rectangle((int) startingPointX, (int) startingPointY,
                    (int) croppedArea.getWidth(), (int) croppedArea.getHeight()));
        }


    }

    void adjustRectangleProperties(Double startingPointX, Double startingPointY, Double currentEndingPointX,
            Double currentEndingPointY, Rectangle givenRectangle) {
        givenRectangle.setX(startingPointX);
        givenRectangle.setY(startingPointY);
        givenRectangle.setWidth(currentEndingPointX - startingPointX);
        givenRectangle.setHeight(currentEndingPointY - startingPointY);
        if (givenRectangle.getWidth() < 0) {
            givenRectangle.setWidth(-givenRectangle.getWidth());
            givenRectangle.setX(givenRectangle.getX() - givenRectangle.getWidth());
        }
        if (givenRectangle.getHeight() < 0) {
            givenRectangle.setHeight(-givenRectangle.getHeight());
            givenRectangle.setY(givenRectangle.getY() - givenRectangle.getHeight());
        }
    }

    public Button createButton(String imageName) throws FileNotFoundException {
        FileInputStream iconFile = new FileInputStream(imageName);
        Image iconImage = new Image(iconFile);
        Button button = new Button();
        button.setGraphic(new ImageView(iconImage));
        button.setMaxSize(20, 20);
        button.setPadding(Insets.EMPTY);
        return button;
    }


    public static void main(String[] args) {
        launch(args);
    }
}

`

mayur singhal
  • 77
  • 1
  • 2
  • 10
  • Could you please publish whole class code (including fields, imports, etc). Would be much easier to recreate. – Przemek Krysztofiak Feb 09 '20 at 10:13
  • @PrzemekKrysztofiak I have put my whole class code with imports and variables. – mayur singhal Feb 09 '20 at 10:47
  • I believe I could help but I'm afraid you need to provide [mcve](https://stackoverflow.com/help/minimal-reproducible-example). Analysing provided code is too much effort on my side. If you decide to create mcve please let me know. – Przemek Krysztofiak Feb 09 '20 at 10:56
  • @PrzemekKrysztofiak i have tried to do that please check – mayur singhal Feb 09 '20 at 11:12
  • @PrzemekKrysztofiak now please check . code is running with minmal code. but free drawings are not drawing – mayur singhal Feb 09 '20 at 11:20
  • you must not sleep the fx application thread, _never-ever_! Though just seeing the one in start, remove it. – kleopatra Feb 09 '20 at 11:21
  • @kleopatra it is working same as before .Nothing happened – mayur singhal Feb 09 '20 at 11:28
  • okay, now strip it down to demonstrate a single problem (vs. multiple) – kleopatra Feb 09 '20 at 12:17
  • @kleopatra check why pencil is not working on click of that button showing on rectangle if you check code by running it – mayur singhal Feb 09 '20 at 13:01
  • @mayursinghal Please fix `image = ConvertBufferedToJavaFXImage.convertToFxImage(bufferedImage);` line which gives compilation error `ConvertBufferedToJavaFXImage cannot be resolved` and I'll try to help. – Przemek Krysztofiak Feb 09 '20 at 13:45
  • @mayursinghal I glanced the code. There is something like `save.png`. Is it really a must have for mcve? Think about it as you would try to help somebody else. Could you run published code easly? Is the published code focused on feature you find troubling to work? Or is it - I don't know, I'll just paste everything. Please put some effort in. – Przemek Krysztofiak Feb 09 '20 at 13:56
  • @PrzemekKrysztofiak sorry for that .please change save.png to some text on button – mayur singhal Feb 09 '20 at 15:09
  • Does this answer your question? [How to draw a continuous line with mouse on JavaFX canvas?](https://stackoverflow.com/questions/43429251/how-to-draw-a-continuous-line-with-mouse-on-javafx-canvas) – fuggerjaki61 Feb 09 '20 at 17:14
  • @fuggerjaki61 i want to draw line on image.this code is for simple canvas.please help me to do that. – mayur singhal Feb 10 '20 at 16:49
  • maybe [this](https://stackoverflow.com/questions/24681018/drawing-user-input-on-image-javafx) helps you :) – fuggerjaki61 Feb 11 '20 at 14:44
  • @kleopatra i got my answer made rectange of 5 px on drag and added that on group that made my free draw line but have some issue how to make that smooth without any gap. Can you please help me – mayur singhal Feb 20 '20 at 18:26
  • @fuggerjaki61 can you please also help and check my above written comment. – mayur singhal Feb 20 '20 at 18:29
  • can you please add how it behaves? does it work? are there exceptions? – fuggerjaki61 Feb 20 '20 at 18:32
  • @fuggerjaki61 yes it is working but if u move the mouse faster it leaves some spaces b/w them like ---- --- - - - - using minus sign to represent my line – mayur singhal Feb 21 '20 at 15:59
  • try to optimize the code runtime. i also found [this question](https://stackoverflow.com/questions/16209512/is-there-any-javafx-image-editor) – fuggerjaki61 Feb 21 '20 at 20:22

0 Answers0