diff --git a/lab-03/pom.xml b/lab-03/pom.xml
new file mode 100644
index 0000000..554841e
--- /dev/null
+++ b/lab-03/pom.xml
@@ -0,0 +1,79 @@
+
+
+ 4.0.0
+
+ com.example
+ lab-03
+ 1.0-SNAPSHOT
+ lab-03
+
+
+ UTF-8
+5.9.2
+
+
+
+ org.openjfx
+ javafx-swing
+ 22-ea+16
+
+
+ org.openjfx
+ javafx-controls
+ 21-ea+24
+
+
+ org.openjfx
+ javafx-fxml
+ 21-ea+24
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.version}
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.11.0
+
+ 21
+ 21
+
+
+
+ org.openjfx
+ javafx-maven-plugin
+ 0.0.8
+
+
+
+ default-cli
+
+ com.example.lab03/by.fact0rial.paint.HelloApplication
+ app
+ app
+ app
+ true
+ true
+ true
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lab-03/src/main/java/by/fact0rial/paint/Main.java b/lab-03/src/main/java/by/fact0rial/paint/Main.java
new file mode 100644
index 0000000..3986441
--- /dev/null
+++ b/lab-03/src/main/java/by/fact0rial/paint/Main.java
@@ -0,0 +1,24 @@
+package by.fact0rial.paint;
+
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+import java.io.IOException;
+
+public class Main extends Application {
+ @Override
+ public void start(Stage stage) throws IOException {
+ FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("view.fxml"));
+ Scene scene = new Scene(fxmlLoader.load(), 1800, 1000);
+ stage.setTitle("Paint");
+ stage.setMaximized(true);
+ stage.setScene(scene);
+ stage.show();
+ }
+
+ public static void main(String[] args) {
+ launch();
+ }
+}
\ No newline at end of file
diff --git a/lab-03/src/main/java/by/fact0rial/paint/Mode.java b/lab-03/src/main/java/by/fact0rial/paint/Mode.java
new file mode 100644
index 0000000..6a88d7c
--- /dev/null
+++ b/lab-03/src/main/java/by/fact0rial/paint/Mode.java
@@ -0,0 +1,5 @@
+package by.fact0rial.paint;
+
+public enum Mode {
+ Line, Circle, Rectangle, Draw, FilledCircle, FilledRectangle
+}
diff --git a/lab-03/src/main/java/by/fact0rial/paint/MyController.java b/lab-03/src/main/java/by/fact0rial/paint/MyController.java
new file mode 100644
index 0000000..37dbddf
--- /dev/null
+++ b/lab-03/src/main/java/by/fact0rial/paint/MyController.java
@@ -0,0 +1,150 @@
+package by.fact0rial.paint;
+
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Group;
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.control.Button;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.control.Label;
+import javafx.scene.control.Slider;
+import javafx.scene.image.Image;
+import javafx.scene.image.WritableImage;
+import javafx.scene.input.MouseDragEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Line;
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+import java.awt.image.BufferedImage;
+import javafx.embed.swing.SwingFXUtils;
+
+import javax.imageio.ImageIO;
+import java.io.File;
+import java.io.IOException;
+
+public class MyController {
+ @FXML
+ private Canvas canvas;
+ @FXML
+ private ColorPicker lineColor;
+ @FXML
+ private ColorPicker fillColor;
+ private GraphicsContext g = null;
+ @FXML
+ private Slider thickness;
+ Mode m = Mode.Draw;
+ double startX = 0;
+ double startY = 0;
+ public void initialize() {
+ g = canvas.getGraphicsContext2D();
+ lineColor.setValue(Color.BLACK);
+ fillColor.setValue(Color.AQUA);
+ canvas.setOnMousePressed(this::mousePress);
+ canvas.setOnMouseDragged(this::mouseDrag);
+ canvas.setOnMouseReleased(this::mouseDragExited);
+ }
+
+ public void onDrawButtonPress() {
+ m = Mode.Draw;
+ }
+ public void onCircleButtonPress() {
+ m = Mode.Circle;
+ }
+ public void onRectangleButtonPress() {
+ m = Mode.Rectangle;
+ }
+ public void onLineButtonPress() {
+ m = Mode.Line;
+ }
+ private void mousePress(MouseEvent e) {
+ g.setLineWidth(thickness.getValue());
+ g.setStroke(lineColor.getValue());
+ g.setFill(fillColor.getValue());
+ switch (m) {
+ case Draw -> {
+ g.beginPath();
+ g.moveTo(e.getX(), e.getY());
+ g.stroke();
+ }
+ case Circle, Rectangle, Line, FilledRectangle, FilledCircle -> {
+ startX = e.getX();
+ startY = e.getY();
+ }
+ }
+ }
+ private void mouseDrag(MouseEvent e) {
+ switch (m) {
+ case Draw -> {
+ g.lineTo(e.getX(), e.getY());
+ g.stroke();
+ }
+ }
+ }
+ private void mouseDragExited(MouseEvent e) {
+ double x1 = Math.min(startX, e.getX());
+ double x2 = Math.abs(startX - e.getX());
+ double y1 = Math.min(startY, e.getY());
+ double y2 = Math.abs(startY - e.getY());
+ switch (m) {
+ case Circle -> {
+ g.strokeOval(x1, y1, x2, y2);
+ }
+ case Rectangle -> {
+ g.strokeRect(x1, y1, x2, y2);
+ }
+ case FilledCircle -> {
+ g.fillOval(x1,y1,x2,y2);
+ g.strokeOval(x1, y1, x2, y2);
+ }
+ case FilledRectangle -> {
+ g.fillRect(x1, y1, x2, y2);
+ g.strokeRect(x1, y1, x2, y2);
+ }
+ case Line -> {
+ g.strokeLine(startX, startY, e.getX(), e.getY());
+ }
+ }
+ }
+
+ public void onFilledCircleButtonPress() {
+ m = Mode.FilledCircle;
+ }
+
+ public void onFilledRectangleButtonPress() {
+ m = Mode.FilledRectangle;
+ }
+
+ public void onSaveButtonPress(ActionEvent actionEvent) {
+ FileChooser chooser = new FileChooser();
+ Stage stage = (Stage)((Button)actionEvent.getSource()).getScene().getWindow();
+ File file = chooser.showSaveDialog(stage);
+ WritableImage im = new WritableImage((int)canvas.getWidth(), (int)canvas.getHeight());
+ canvas.snapshot(null, im);
+ BufferedImage buff = SwingFXUtils.fromFXImage(im, null);
+ try {
+ ImageIO.write(buff, "png", file);
+ } catch (IOException e) {
+ System.out.println("Ошибка при сохранении рисунка: " + e.getMessage());
+ }
+ }
+
+ public void onOpenButtonPress(ActionEvent actionEvent) {
+ FileChooser chooser = new FileChooser();
+ chooser.getExtensionFilters().addAll(
+ new FileChooser.ExtensionFilter("PNG Files", "*.png"));
+ Stage stage = (Stage)((Button)actionEvent.getSource()).getScene().getWindow();
+ File file = chooser.showOpenDialog(stage);
+ BufferedImage buff = null;
+ try {
+ buff = ImageIO.read(file);
+ } catch (IOException e) {
+ System.out.println("Ошибка при открытии рисунка: " + e.getMessage());
+ }
+ Image im = SwingFXUtils.toFXImage(buff, null);
+ g.fillRect(0,0, canvas.getWidth(), canvas.getHeight());
+ g.drawImage(im, 0, 0);
+ }
+}
\ 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..8a8f8bf
--- /dev/null
+++ b/lab-03/src/main/java/module-info.java
@@ -0,0 +1,10 @@
+module com.example.lab03 {
+ requires javafx.controls;
+ requires javafx.fxml;
+ requires java.desktop;
+ requires javafx.swing;
+
+
+ opens by.fact0rial.paint to javafx.fxml;
+ exports by.fact0rial.paint;
+}
\ No newline at end of file
diff --git a/lab-03/src/main/resources/by/fact0rial/paint/view.fxml b/lab-03/src/main/resources/by/fact0rial/paint/view.fxml
new file mode 100644
index 0000000..036dc7b
--- /dev/null
+++ b/lab-03/src/main/resources/by/fact0rial/paint/view.fxml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+