feat: début environnement graphique, dessin fonctionnel, sauvegarde et chargement temporaire possible

This commit is contained in:
Emi Boucly 2025-03-17 11:14:27 +01:00
parent 8af801e4fd
commit 70e583a380
6 changed files with 195 additions and 19 deletions

View file

@ -36,7 +36,13 @@
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency> </dependencies>
</dependency>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>11.2.1</version>
</dependency>
</dependencies>
<build>
<plugins>

View file

@ -12,7 +12,7 @@ public class HelloApplication extends Application {
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setTitle("PixelWriter");
stage.setScene(scene);
stage.show();
}

View file

@ -1,14 +1,100 @@
package fr.emiko.graphicalapp;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Label;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.MenuItem;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import fr.emiko.graphicsElement.Stroke;
public class HelloController {
@FXML
private Label welcomeText;
import java.awt.*;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Vector;
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
public class HelloController implements Initializable {
public Canvas drawingCanvas;
public MenuItem saveButton;
public MenuItem loadButton;
public MenuItem newCanvasButton;
private double posX = 0;
private double posY = 0;
private Vector<Stroke> strokes = new Vector<>();
private Vector<Stroke> lastSaved = new Vector<>();
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
drawingCanvas.setOnMouseDragged(this::printLine);
drawingCanvas.setOnMouseClicked(this::resetPos);
saveButton.setOnAction(this::onActionSave);
loadButton.setOnAction(this::onActionLoad);
newCanvasButton.setOnAction(this::onActionCreateCanvas);
}
private void onActionCreateCanvas(ActionEvent actionEvent) {
}
private void onActionLoad(ActionEvent actionEvent) {
// drawingCanvas.getGraphicsContext2D().drawImage(lastSaved, 0, 0);
GraphicsContext gc = drawingCanvas.getGraphicsContext2D();
gc.clearRect(0, 0, drawingCanvas.getWidth(), drawingCanvas.getHeight());
for (Stroke stroke : lastSaved) {
stroke.draw(gc);
}
strokes = (Vector<Stroke>) lastSaved.clone();
}
private void onActionSave(ActionEvent actionEvent) {
GraphicsContext gc = drawingCanvas.getGraphicsContext2D();
lastSaved = (Vector<Stroke>) strokes.clone();
}
private void resetPos(MouseEvent mouseEvent) {
posX = 0;
posY = 0;
}
private void printLine(MouseEvent mouseEvent) {
GraphicsContext gc = drawingCanvas.getGraphicsContext2D();
// gc.setFill(Color.BLACK);
// gc.setStroke(Color.BLACK);
// gc.beginPath();
// if (posX == 0 || posY == 0) {
// posX = mouseEvent.getX();
// posY = mouseEvent.getY();
// }
// gc.moveTo(posX, posY);
// gc.lineTo(mouseEvent.getX(), mouseEvent.getY());
// gc.closePath();
// gc.stroke();
// posX = mouseEvent.getX();
// posY = mouseEvent.getY();
if (posX == 0 || posY == 0) {
posX = mouseEvent.getX();
posY = mouseEvent.getY();
}
Stroke stroke = new Stroke(posX, posY, mouseEvent.getX(), mouseEvent.getY());
strokes.add(stroke);
stroke.draw(gc);
posX = mouseEvent.getX();
posY = mouseEvent.getY();
System.out.println(stroke);
}
}

View file

@ -0,0 +1,39 @@
package fr.emiko.graphicsElement;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.shape.Path;
import java.awt.*;
public class Stroke {
private final double fromX;
private final double fromY;
private final double toX;
private final double toY;
public Stroke (double fromX, double fromY, double toX, double toY) {
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
}
public void draw (GraphicsContext g) {
// g.setStroke(javafx.scene.paint.Color.BLACK);
// g.setLineWidth(1);
// g.beginPath();
// g.moveTo(fromX, fromY);
// g.lineTo(toX, toY);
// g.closePath();
// g.stroke();
// g.fill();
g.setFill(javafx.scene.paint.Color.BLACK);
g.fillOval(toX-5, toY-5, 10, 10);
}
@Override
public String toString () {
return "Stroke{fromX=%f, fromY=%f, toX=%f, toY=%f}".formatted(fromX, fromY, toX, toY);
}
}

View file

@ -1,6 +1,8 @@
module fr.emiko.graphicalapp {
requires javafx.controls;
requires javafx.fxml;
requires java.desktop;
requires org.controlsfx.controls;
opens fr.emiko.graphicalapp to javafx.fxml;

View file

@ -1,16 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="fr.emiko.graphicalapp.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</padding>
<Label fx:id="welcomeText"/>
<Button text="Hello!" onAction="#onHelloButtonClick"/>
<VBox alignment="CENTER" xmlns="http://javafx.com/javafx/23.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.emiko.graphicalapp.HelloController">
<children>
<MenuBar VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem fx:id="newCanvasButton" mnemonicParsing="false" text="New canvas" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem fx:id="saveButton" mnemonicParsing="false" text="Save" />
<MenuItem fx:id="loadButton" mnemonicParsing="false" text="Load" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
<SplitPane dividerPositions="0.11195652173913044" VBox.vgrow="ALWAYS">
<items>
<VBox prefHeight="200.0" prefWidth="100.0" />
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" />
<ColumnConstraints hgrow="SOMETIMES" />
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="ALWAYS" />
<RowConstraints vgrow="SOMETIMES" />
</rowConstraints>
<children>
<ScrollPane hbarPolicy="ALWAYS" style="-fx-background-color: #666666; -fx-background: #666666;" vbarPolicy="ALWAYS" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS">
<content>
<Canvas fx:id="drawingCanvas" height="600.0" nodeOrientation="INHERIT" width="800.0" />
</content>
</ScrollPane>
</children>
</GridPane>
</items>
</SplitPane>
</children>
</VBox>