Перетащить линию в пределах Canvas - Java
Формулировка задачи:
Как можно перенести линию мышью в пределах границ холста?
если использовать метод setOnMouseMoved то он перерисовывает нужную линию вслед за движениями мыши, но во время клика мыши не может закрепить в нужном месте, пока мышь двигается линия так и будет двигаться без остановки.
если применить метод setOnMouseDragged, то он перемещает геометрические примитивы созданные как объект, и перемещает за пределы холста, но зато если кнопку мыши отпустить то перемещение останавливается
....
....
public class Canv extends Application {
private double x;
private double y;
private double xO;
private double yO;
Canvas myCanvas;
GraphicsContext gc;
private void Shapes(GraphicsContext gc) {
GL();
gc.strokeRect(2, 2, myCanvas.getWidth() - 3, myCanvas.getHeight() - 3); // границы холста
gc.strokeLine(50, 80, 200, 80);
gc.strokeLine(50, 110, 200, 110);
gc.strokeLine(50, 140, 200, 140); // линия которую требуется перетащить
gc.strokeLine(50+x, 140, 200+x, 140); //
}
public void GL() {
myCanvas.setOnMouseMoved(new EventHandler<MouseEvent>() {
public void handle(MouseEvent e) {
x = e.getX() - 40; // 40 левый отступ AnchorPane.setLeftAnchor(myCanvas, 40.0);
y = e.getY();
gc.clearRect(0, 0, myCanvas.getWidth(), myCanvas.getHeight());
gc.strokeRect(2, 2, myCanvas.getWidth() - 3, myCanvas.getHeight() - 3);
Shapes(gc);
}
});
}
public static void main(String[] args) {
launch(args);
}
public void start(Stage myStage) throws Exception {
myStage.setTitle("Title");
AnchorPane rootPane = new AnchorPane();
Scene myScene = new Scene(rootPane, 700, 400);
myStage.setScene(myScene);
// Canvas
myCanvas = new Canvas(500, 360);
gc = myCanvas.getGraphicsContext2D();
gc.strokeRect(2, 2, myCanvas.getWidth() - 3, myCanvas.getHeight() - 3);
Shapes(gc);
Pane p = new Pane();
Rectangle rect = new Rectangle(40, 20, 50, 100);
p.getChildren().add(rect);
p.setOnMousePressed(new EventHandler<MouseEvent>() {
public void handle(MouseEvent e) {
xO = rect.getX() - e.getScreenX();
yO = rect.getY() - e.getScreenY(); }
});
p.setOnMouseDragged(new EventHandler<MouseEvent>() {
public void handle(MouseEvent e) {
rect.setX(e.getScreenX() + xO); // перемещает прямоугольник за пределы myCanvas
rect.setY(e.getScreenY() + yO);
}
});
// привязки холста
AnchorPane.setLeftAnchor(myCanvas, 40.0);
AnchorPane.setTopAnchor(myCanvas, 20.0);
rootPane.getChildren().add(myCanvas);
rootPane.getChildren().add(p);
myStage.show();
}
}Решение задачи: «Перетащить линию в пределах Canvas»
textual
Листинг программы
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Exp extends Application {
Canvas myCanvas;
GraphicsContext gc;
private double x;
private double y;
private double xO;
private double yO;
private boolean moved = true;
public static void main(String[] args) {
launch(args);
}
private void Shapes(GraphicsContext gc) {
GL();
gc.strokeRect(2, 2, myCanvas.getWidth() - 3, myCanvas.getHeight() - 3); // границы холста
gc.strokeLine(50, 80, 200, 80);
gc.strokeLine(50, 110, 200, 110);
gc.strokeLine(50, 140, 200, 140); // линия которую требуется перетащить
gc.strokeLine(x, 140, x + 150, 140); //
}
public void GL() {
myCanvas.setOnMouseMoved(e -> {
if (moved) {
x = Math.min(e.getX(), myCanvas.getWidth() - 150); // 40 левый отступ AnchorPane.setLeftAnchor(myCanvas, 40.0);
y = e.getY();
gc.clearRect(0, 0, myCanvas.getWidth(), myCanvas.getHeight());
gc.strokeRect(2, 2, myCanvas.getWidth() - 3, myCanvas.getHeight() - 3);
Shapes(gc);
}
});
myCanvas.setOnMouseClicked(event -> moved = !moved);
}
public void start(Stage myStage) throws Exception {
myStage.setTitle("Title");
AnchorPane rootPane = new AnchorPane();
Scene myScene = new Scene(rootPane, 700, 400);
myStage.setScene(myScene);
// Canvas
myCanvas = new Canvas(500, 360);
gc = myCanvas.getGraphicsContext2D();
gc.strokeRect(2, 2, myCanvas.getWidth() - 3, myCanvas.getHeight() - 3);
Shapes(gc);
Rectangle rect = new Rectangle(40, 20, 50, 100);
rect.setOnMousePressed(e -> {
xO = rect.getX() - e.getSceneX();
yO = rect.getY() - e.getSceneY();
});
rect.setOnMouseDragged(e -> {
double posX = e.getSceneX() + xO;
double posY = e.getSceneY() + yO;
if (posX < 40) posX = 40;
else if (posX + rect.getWidth() > 40 + myCanvas.getWidth())
posX = 40 + myCanvas.getWidth() - rect.getWidth();
if (posY < 20) posY = 20;
else if (posY + rect.getHeight() > 20 + myCanvas.getHeight())
posY = 20 + myCanvas.getHeight() - rect.getHeight();
rect.setX(posX);
rect.setY(posY);
});
// привязки холста
AnchorPane.setLeftAnchor(myCanvas, 40.0);
AnchorPane.setTopAnchor(myCanvas, 20.0);
rootPane.getChildren().add(myCanvas);
rootPane.getChildren().add(rect);
myStage.show();
}
}