Skip to content
Open

Lab3 #62

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 167 additions & 0 deletions lab-03/by/nrydo/paint/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
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 Canvas upperCanvas;
@FXML
private Slider brushSize;
@FXML
private ComboBox<DrawingMode> modeChooser;
@FXML
private ColorPicker firstColorPicker;
@FXML
private ColorPicker secondColorPicker;
private GraphicsContext graphicsContext;
private GraphicsContext mainContext;
private double fixedX;
private double fixedY;

public void initialize() {
graphicsContext = upperCanvas.getGraphicsContext2D();
mainContext = canvas.getGraphicsContext2D();
clearImage();
clearUpperCanvas();
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();
mainContext.beginPath();
clearUpperCanvas();
}

public void mouseReleased(MouseEvent event) {
draw(mainContext, event);
}

public void mouseDragged(MouseEvent event) {
switch (modeChooser.getValue()) {
case LINE, RECTANGLE, ELLIPSE:
draw(graphicsContext, event);
break;
case PEN, ERASER:
draw(mainContext, event);
break;
}
}

public void draw(GraphicsContext context, MouseEvent event) {
double curX = event.getX();
double curY = event.getY();

context.setLineWidth(brushSize.getValue());

switch (event.getButton()) {
case MouseButton.PRIMARY:
context.setStroke(firstColorPicker.getValue());
break;
case MouseButton.SECONDARY:
context.setStroke(secondColorPicker.getValue());
break;
default:
return;
}

switch (modeChooser.getValue()) {
case PEN:
context.lineTo(curX, curY);
context.stroke();
break;
case LINE:
clearUpperCanvas();
context.strokeLine(fixedX, fixedY, curX, curY);
break;
case RECTANGLE:
clearUpperCanvas();
context.strokeRect(Math.min(fixedX, curX), Math.min(fixedY, curY), Math.abs(curX - fixedX), Math.abs(curY - fixedY));
break;
case ELLIPSE:
clearUpperCanvas();
context.strokeOval(Math.min(fixedX, curX), Math.min(fixedY, curY), Math.abs(curX - fixedX), Math.abs(curY - fixedY));
break;
case ERASER:
context.setStroke(secondColorPicker.getValue());
context.lineTo(curX, curY);
context.stroke();
break;
}
}

public void swapColors() {
var buffer = firstColorPicker.getValue();
firstColorPicker.setValue(secondColorPicker.getValue());
secondColorPicker.setValue(buffer);
}

public void clearImage() {
mainContext.setFill(Color.WHITE);
mainContext.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
}

public void clearUpperCanvas() {
graphicsContext.clearRect(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();
mainContext.drawImage(image, 0, 0, canvas.getWidth(), canvas.getHeight());
}
}
}
11 changes: 11 additions & 0 deletions lab-03/by/nrydo/paint/DrawingMode.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
20 changes: 20 additions & 0 deletions lab-03/by/nrydo/paint/Paint.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
40 changes: 40 additions & 0 deletions lab-03/by/nrydo/paint/paint.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.canvas.Canvas?>

<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="by.nrydo.paint.Controller"
prefWidth="800.0" prefHeight="600.0">
<top>
<VBox>
<ToolBar>
<HBox alignment="CENTER" spacing="5">
<Button text="Save" onAction="#saveImage"/>
<Button text="Open" onAction="#openImage"/>
<Button text="Clear" onAction="#clearImage"/>
<ColorPicker fx:id="firstColorPicker"/>
<Button text="↔" onAction="#swapColors"/>
<ColorPicker fx:id="secondColorPicker"/>
<ComboBox fx:id="modeChooser">
</ComboBox>
<HBox spacing="5">
<Label text="Brush Size:"/>
<Slider fx:id="brushSize" min="1" max="30" value="5" blockIncrement="1" showTickMarks="true"/>
</HBox>
</HBox>
</ToolBar>
</VBox>
</top>

<center>
<Pane>
<Canvas fx:id="canvas" width="800" height="600"/>
<Canvas fx:id="upperCanvas" width="800" height="600" onMousePressed="#mousePressed"
onMouseDragged="#mouseDragged" onMouseReleased="#mouseReleased"/>
</Pane>
</center>

</BorderPane>