Я недавно перешел на JavaFX для создания программы рисования с использованием мыши. Я столкнулся с проблемой, пытаясь наложить прямоугольник на свой холст - он, кажется, не go, где я хочу. Я потратил часы, пытаясь взломать это, и я думаю, что мне нужна помощь. Код ниже:
Кажется, проблема в том, что координаты продолжают обновляться, пока я двигаю мышью, чего я не хочу, чтобы это происходило. Я хочу, чтобы пользователь щелкнул мышью и перетащил ее, а затем в конце прямоугольник будет создан на основе координат движения мыши. То же самое происходит и с инструментом линии, так как он будет работать точно так же, как инструмент bru sh, и все больше и больше фигур опускаются при перемещении мыши по экрану. Все это относится к классу контроллеров.
Основной класс
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(FXMLLoader.load(getClass().getResource("sample.fxml"))));
stage.setTitle("Paint");
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Контроллер
package sample;
import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.Image;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.io.File;
public class Controller {
int prevX, prevY, startX, startY, x , y;
boolean dragging;
@FXML
private Canvas canvas;
@FXML
private ColorPicker colorPicker;
@FXML
private TextField brushSize;
@FXML
private ToggleButton eraser;
@FXML
private ToggleButton line;
@FXML
private ToggleButton rectangle;
public void initialize() {
GraphicsContext g = canvas.getGraphicsContext2D();
canvas.setOnMousePressed(e -> {
startX = prevX = x = (int) e.getX();
startX = prevY = y = (int) e.getY();
dragging = true;
});
canvas.setOnMouseReleased(e -> {
dragging = false;
});
canvas.setOnMouseDragged(e -> {
double size = Double.parseDouble(brushSize.getText());
if(!dragging)
return;
double x = e.getX();
double y = e.getY();
if(eraser.isSelected()) {
g.clearRect(x, y, size, size);
} else if(line.isSelected()) {
g.strokeLine(prevX, prevY, x, y); // also experiencing issues
} else if(rectangle.isSelected()) {
putRect(g, false, startX, startY, x, y); // this puts the rectangle on the canvas
} else {
g.setStroke(colorPicker.getValue());
g.setLineWidth(size);
g.strokeLine(prevX, prevY, x, y);
}
prevX = (int) x;
prevY = (int) y;
});
}
public void putRect(GraphicsContext g, boolean filled, int x1, int y1, int x2, int y2) { // to create the rectangle
if(x1 == x2 || y1 == y2) {
return;
} else {
int x = Math.min(x1,x2); // get upper left corner, (x,y)
int y = Math.min(y1,y2);
int w = Math.abs(x1 - x2); // get width and height
int h = Math.abs(y1 - y2);
if (filled) {
g.fillRect(x, y, w, h);
} else {
g.strokeRect(x, y, w, h);
}
}
}
public void onSave() {
try{
Image snapshot = canvas.snapshot(null, null);
ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "png", new File("paintsave.png"));
} catch (Exception e) {
System.out.println("Failed to save: " + e);
}
}
public void onExit() {
Platform.exit();
}
}
F XML
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ColorPicker?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.control.ToggleButton?>
<BorderPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml"
prefHeight="600.0" prefWidth="600.0">
<top>
<VBox>
<MenuBar>
<Menu text="file">
<MenuItem text="Save" onAction="#onSave"/>
<MenuItem text="Exit" onAction="#onExit"/>
</Menu>
</MenuBar>
<ToolBar>
<HBox alignment="CENTER" spacing="5">
<TextField fx:id="brushSize" text="18"/>
<ColorPicker fx:id="colorPicker"/>
<ToggleButton fx:id="eraser" text="Eraser"/>
<ToggleButton fx:id="line" text="Line"/>
<ToggleButton fx:id="rectangle" text="Rectangle"/>
</HBox>
</ToolBar>
</VBox>
</top>
<center>
<Canvas fx:id="canvas" width="600" height="600"/>
</center>
</BorderPane>