From ee393ff9c8df7065a01a123fed0f0a71a5db18f0 Mon Sep 17 00:00:00 2001 From: Nrydo Date: Mon, 25 Dec 2023 01:51:47 +0300 Subject: [PATCH 1/2] lab-03 --- lab-03/by/nrydo/paint/Controller.java | 148 +++++++++++++++++++++++++ lab-03/by/nrydo/paint/DrawingMode.java | 11 ++ lab-03/by/nrydo/paint/Paint.java | 20 ++++ lab-03/by/nrydo/paint/paint.fxml | 37 +++++++ 4 files changed, 216 insertions(+) create mode 100644 lab-03/by/nrydo/paint/Controller.java create mode 100644 lab-03/by/nrydo/paint/DrawingMode.java create mode 100644 lab-03/by/nrydo/paint/Paint.java create mode 100644 lab-03/by/nrydo/paint/paint.fxml diff --git a/lab-03/by/nrydo/paint/Controller.java b/lab-03/by/nrydo/paint/Controller.java new file mode 100644 index 0000000..015823e --- /dev/null +++ b/lab-03/by/nrydo/paint/Controller.java @@ -0,0 +1,148 @@ +package by.nrydo.paint; + +import javafx.fxml.FXML; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.control.ColorPicker; +import javafx.collections.FXCollections; +import javafx.scene.image.WritableImage; +import javafx.scene.control.Slider; +import javafx.scene.control.ComboBox; +import javafx.scene.image.Image; +import javafx.scene.input.MouseButton; +import javafx.stage.Stage; +import javafx.scene.canvas.Canvas; +import javafx.scene.paint.Color; +import javafx.scene.shape.StrokeLineCap; +import javafx.scene.canvas.GraphicsContext; +import javafx.scene.shape.StrokeLineJoin; +import javafx.scene.input.MouseEvent; +import javafx.stage.FileChooser; + +import javax.imageio.ImageIO; +import java.io.IOException; +import java.io.File; + +public class Controller { + @FXML + private Canvas canvas; + @FXML + private Slider brushSize; + @FXML + private ComboBox modeChooser; + @FXML + private ColorPicker firstColorPicker; + @FXML + private ColorPicker secondColorPicker; + private GraphicsContext graphicsContext; + private WritableImage image; + private double fixedX; + private double fixedY; + + public void initialize() { + graphicsContext = canvas.getGraphicsContext2D(); + graphicsContext.setFill(Color.WHITE); + graphicsContext.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); + modeChooser.setItems(FXCollections.observableArrayList(DrawingMode.values())); + modeChooser.setValue(DrawingMode.PEN); + firstColorPicker.setValue(Color.BLACK); + secondColorPicker.setValue(Color.WHITE); + brushSize.setValue(5); + graphicsContext.setLineCap(StrokeLineCap.ROUND); + graphicsContext.setLineJoin(StrokeLineJoin.ROUND); + fixedX = 0; + fixedY = 0; + } + + public void mousePressed(MouseEvent event) { + fixedX = event.getX(); + fixedY = event.getY(); + graphicsContext.beginPath(); + image = canvas.snapshot(null, null); + } + + public void mouseReleased(MouseEvent event) { + image = canvas.snapshot(null, null); + } + + public void mouseDragged(MouseEvent event) { + double size = brushSize.getValue(); + double curX = event.getX(); + double curY = event.getY(); + + graphicsContext.setLineWidth(size); + switch (event.getButton()) { + case MouseButton.PRIMARY: + graphicsContext.setStroke(firstColorPicker.getValue()); + break; + case MouseButton.SECONDARY: + graphicsContext.setStroke(secondColorPicker.getValue()); + break; + default: + return; + } + + switch (modeChooser.getValue()) { + case PEN: + graphicsContext.lineTo(event.getX(), event.getY()); + graphicsContext.stroke(); + break; + case LINE: + graphicsContext.drawImage(image, 0, 0, canvas.getHeight(), canvas.getWidth()); + graphicsContext.strokeLine(fixedX, fixedY, curX, curY); + break; + case RECTANGLE: + graphicsContext.drawImage(image, 0, 0, canvas.getHeight(), canvas.getWidth()); + graphicsContext.strokeRect(Math.min(fixedX, curX), Math.min(fixedY, curY), Math.abs(curX - fixedX), Math.abs(curY - fixedY)); + break; + case ELLIPSE: + graphicsContext.drawImage(image, 0, 0, canvas.getHeight(), canvas.getWidth()); + graphicsContext.strokeOval(Math.min(fixedX, curX), Math.min(fixedY, curY), Math.abs(curX - fixedX), Math.abs(curY - fixedY)); + break; + case ERASER: + graphicsContext.setStroke(secondColorPicker.getValue()); + graphicsContext.lineTo(event.getX(), event.getY()); + graphicsContext.stroke(); + break; + } + } + + public void swapColors() { + var buffer = firstColorPicker.getValue(); + firstColorPicker.setValue(secondColorPicker.getValue()); + secondColorPicker.setValue(buffer); + } + + public void clearImage() { + graphicsContext.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); + } + + public void saveImage() { + Stage stage = new Stage(); + FileChooser fileChooser = new FileChooser(); + fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Image", "*.png")); + File file = fileChooser.showSaveDialog(stage); + + if (file != null) { + try { + WritableImage temp = new WritableImage((int) canvas.getWidth(), (int) canvas.getHeight()); + canvas.snapshot(null, temp); + ImageIO.write(SwingFXUtils.fromFXImage(temp, null), "png", file); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public void openImage() { + Stage stage = new Stage(); + FileChooser fileChooser = new FileChooser(); + fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Image", "*.png", "*.jpg")); + File file = fileChooser.showOpenDialog(stage); + + if (file != null) { + Image image = new Image(file.toURI().toString()); + clearImage(); + canvas.getGraphicsContext2D().drawImage(image, 0, 0, canvas.getWidth(), canvas.getHeight()); + } + } +} \ No newline at end of file diff --git a/lab-03/by/nrydo/paint/DrawingMode.java b/lab-03/by/nrydo/paint/DrawingMode.java new file mode 100644 index 0000000..2b45f8e --- /dev/null +++ b/lab-03/by/nrydo/paint/DrawingMode.java @@ -0,0 +1,11 @@ +package by.nrydo.paint; + +public enum DrawingMode { + PEN, LINE, ELLIPSE, RECTANGLE, ERASER; + + @Override + public String toString() { + String name = name().toLowerCase(); + return name.substring(0, 1).toUpperCase() + name.substring(1); + } +} diff --git a/lab-03/by/nrydo/paint/Paint.java b/lab-03/by/nrydo/paint/Paint.java new file mode 100644 index 0000000..674ccb9 --- /dev/null +++ b/lab-03/by/nrydo/paint/Paint.java @@ -0,0 +1,20 @@ +package by.nrydo.paint; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.stage.Stage; +import java.util.Objects; + +public class Paint extends Application { + @Override + public void start(Stage stage) throws Exception { + stage.setTitle("Paint"); + stage.setScene(new Scene(FXMLLoader.load(Objects.requireNonNull(getClass().getResource("paint.fxml"))))); + stage.show(); + } + + public static void main(String[] args) { + launch(args); + } +} diff --git a/lab-03/by/nrydo/paint/paint.fxml b/lab-03/by/nrydo/paint/paint.fxml new file mode 100644 index 0000000..955f467 --- /dev/null +++ b/lab-03/by/nrydo/paint/paint.fxml @@ -0,0 +1,37 @@ + + + + + + + + + + + +