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 @@ + + + + + + + + + + + + + +