From f3002b938973d6c1849c4b0b509310e0485a6c86 Mon Sep 17 00:00:00 2001 From: mikhail Date: Sun, 24 Dec 2023 15:53:45 +0300 Subject: [PATCH 1/3] lab-03 --- lab-03/pom.xml | 81 +++++++++ .../java/by/MikhailShurov/paint/PaintApp.java | 168 ++++++++++++++++++ lab-03/src/main/java/module-info.java | 10 ++ 3 files changed, 259 insertions(+) create mode 100644 lab-03/pom.xml create mode 100644 lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java create mode 100644 lab-03/src/main/java/module-info.java diff --git a/lab-03/pom.xml b/lab-03/pom.xml new file mode 100644 index 0000000..2d8d616 --- /dev/null +++ b/lab-03/pom.xml @@ -0,0 +1,81 @@ + + + 4.0.0 + + org.example + demo + 1.0-SNAPSHOT + demo + + + UTF-8 + 5.10.0 + + + + + org.openjfx + javafx-controls + 21 + + + org.openjfx + javafx-fxml + 21 + + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + test + + + org.openjfx + javafx-swing + 22-ea+16 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 21 + 21 + + + + org.openjfx + javafx-maven-plugin + 0.0.8 + + + + default-cli + + org.example.demo/org.example.demo.HelloApplication + app + app + app + true + true + true + + + + + + + \ No newline at end of file diff --git a/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java b/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java new file mode 100644 index 0000000..9eedb73 --- /dev/null +++ b/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java @@ -0,0 +1,168 @@ +package by.MikhailShurov.paint; + +import javafx.application.Application; +import javafx.embed.swing.SwingFXUtils; +import javafx.event.EventHandler; +import javafx.geometry.Insets; +import javafx.scene.Scene; +import javafx.scene.canvas.Canvas; +import javafx.scene.canvas.GraphicsContext; +import javafx.scene.control.Button; +import javafx.scene.control.ColorPicker; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Slider; +import javafx.scene.image.Image; +import javafx.scene.image.WritableImage; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javafx.scene.paint.Color; +import javafx.stage.FileChooser; +import javafx.stage.Stage; + +import javax.imageio.ImageIO; +import java.io.File; +import java.io.IOException; + +public class PaintApp extends Application { + private static final int CANVAS_WIDTH = 1000; + private static final int CANVAS_HEIGHT = 1000; + + private final Canvas canvas = new Canvas(CANVAS_WIDTH, CANVAS_HEIGHT); + private final GraphicsContext gc = canvas.getGraphicsContext2D(); + private ColorPicker colorPicker; + private Slider thicknessSlider; + + private double lastX; + private double lastY; + ComboBox modeComboBox; + WritableImage img; + + private final FileChooser fileChooser = new FileChooser(); + + enum Mode { + Free, Rectangle, Circle + } + + Mode mode = Mode.Free; + + public static void main(String[] args) { + launch(args); + } + + private void drawRectangle(double x1, double y1, double x2, double y2, GraphicsContext currentGc) { + currentGc.strokeRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1)); + } + + private void drawCircle(double x1, double y1, double x2, double y2, GraphicsContext currentGc) { + double radius = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); + currentGc.strokeOval(x1 - radius, y1 - radius, radius * 2, radius * 2); + } + + private void drawLine(double endX, double endY) { + gc.lineTo(endX, endY); + gc.stroke(); + } + + EventHandler mousePressedHandler = event -> { + img = canvas.snapshot(null, null); + lastX = event.getX(); + lastY = event.getY(); + + gc.beginPath(); + gc.setStroke(colorPicker.getValue()); + gc.setFill(colorPicker.getValue()); + gc.setLineWidth(thicknessSlider.getValue()); + }; + + EventHandler mouseDraggedHandler = e -> { + if (mode == Mode.Free) { + drawLine(e.getX(), e.getY()); + } else if (mode == Mode.Rectangle) { + gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight()); + drawRectangle(lastX, lastY, e.getX(), e.getY(), gc); + } else if (mode == Mode.Circle) { + gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight()); + drawCircle(lastX, lastY, e.getX(), e.getY(), gc); + } + }; + + EventHandler mouseReleasedHandler = e -> { + if (mode == Mode.Rectangle) { + gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight()); + drawRectangle(lastX, lastY, e.getX(), e.getY(), gc); + } else if (mode == Mode.Circle) { + gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight()); + drawCircle(lastX, lastY, e.getX(), e.getY(), gc); + } + }; + + private void saveImageToFile() { + fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("PNG Files", "*.png")); + File file = fileChooser.showSaveDialog(null); + if (file != null) { + try { + ImageIO.write(SwingFXUtils.fromFXImage(canvas.snapshot(null, null), null), "png", file); + } catch (IOException e) { + System.out.println(e); + } + } + } + + private void loadImageFromFile() { + File file = fileChooser.showOpenDialog(null); + if (file != null) { + String path = file.toURI().toString(); + Image tmp = new javafx.scene.image.Image(path); + gc.drawImage(tmp, 0, 0); + } + } + + private void clearCanvas() { + gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); + } + + @Override + public void start(Stage primaryStage) { + primaryStage.setResizable(false); + colorPicker = new ColorPicker(Color.BLACK); + + thicknessSlider = new Slider(1,10, 2); + thicknessSlider.setShowTickMarks(true); + thicknessSlider.setShowTickLabels(true); + thicknessSlider.setMajorTickUnit(1); + thicknessSlider.setBlockIncrement(1); + thicknessSlider.setPrefWidth(150); + + canvas.setOnMousePressed(mousePressedHandler); + canvas.setOnMouseDragged(mouseDraggedHandler); + canvas.setOnMouseReleased(mouseReleasedHandler); + + modeComboBox = new ComboBox<>(); + modeComboBox.getItems().addAll(Mode.Free, Mode.Rectangle, Mode.Circle); + modeComboBox.setValue(Mode.Free); + modeComboBox.setOnAction(e -> mode = modeComboBox.getValue()); + + Button saveButton = new Button("Сохранить"); + saveButton.setOnAction(e -> saveImageToFile()); + + Button loadButton = new Button("Загрузить"); + loadButton.setOnAction(e -> loadImageFromFile()); + + Button clearButton = new Button("Очистить"); + clearButton.setOnAction(e -> clearCanvas()); + + HBox controlsBox = new HBox(10); + controlsBox.setPadding(new Insets(10)); + controlsBox.getChildren().addAll(colorPicker, thicknessSlider, modeComboBox, saveButton, loadButton, clearButton); + + BorderPane root = new BorderPane(); + root.setTop(controlsBox); + root.setCenter(canvas); + + Scene scene = new Scene(root, CANVAS_WIDTH, CANVAS_HEIGHT); + primaryStage.setScene(scene); + primaryStage.setTitle("Paint"); + primaryStage.show(); + } +} \ No newline at end of file diff --git a/lab-03/src/main/java/module-info.java b/lab-03/src/main/java/module-info.java new file mode 100644 index 0000000..7b2d7f1 --- /dev/null +++ b/lab-03/src/main/java/module-info.java @@ -0,0 +1,10 @@ +module org.example.demo { + requires javafx.controls; + requires javafx.fxml; + requires java.desktop; + requires javafx.swing; + + + opens by.MikhailShurov.paint to javafx.fxml; + exports by.MikhailShurov.paint; +} \ No newline at end of file From 6f0c2e31265a088c4bab906e74bb07419d8ae854 Mon Sep 17 00:00:00 2001 From: mikhail Date: Wed, 27 Dec 2023 10:18:03 +0300 Subject: [PATCH 2/3] fixed chachged background and blur --- lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java b/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java index 9eedb73..6a9a7dc 100644 --- a/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java +++ b/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java @@ -120,6 +120,8 @@ private void loadImageFromFile() { private void clearCanvas() { gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); + img = canvas.snapshot(null, null); + gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight()); } @Override @@ -138,6 +140,10 @@ public void start(Stage primaryStage) { canvas.setOnMouseDragged(mouseDraggedHandler); canvas.setOnMouseReleased(mouseReleasedHandler); + img = canvas.snapshot(null, null); + gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight()); + + modeComboBox = new ComboBox<>(); modeComboBox.getItems().addAll(Mode.Free, Mode.Rectangle, Mode.Circle); modeComboBox.setValue(Mode.Free); From 614d9801d81922036205de936b807ba69b5f6c1d Mon Sep 17 00:00:00 2001 From: mikhail Date: Wed, 27 Dec 2023 10:22:03 +0300 Subject: [PATCH 3/3] updated... --- lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java b/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java index 6a9a7dc..345f8b6 100644 --- a/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java +++ b/lab-03/src/main/java/by/MikhailShurov/paint/PaintApp.java @@ -120,8 +120,8 @@ private void loadImageFromFile() { private void clearCanvas() { gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); - img = canvas.snapshot(null, null); - gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight()); + gc.setFill(Color.WHITE); + gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); } @Override @@ -140,8 +140,8 @@ public void start(Stage primaryStage) { canvas.setOnMouseDragged(mouseDraggedHandler); canvas.setOnMouseReleased(mouseReleasedHandler); - img = canvas.snapshot(null, null); - gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight()); + gc.setFill(Color.WHITE); + gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); modeComboBox = new ComboBox<>();