JavaFX。画一个球并从它的中心拖出一条线
这个想法是在鼠标上画一个球 从它的中心开始画一条线,直到它在鼠标拖动的处理程序中释放。 但它确实完全相反,我并不是简单地理解它——它首先画了一条线,在我释放鼠标后,球出现了。 有人看到问题出在哪里了吗JavaFX。画一个球并从它的中心拖出一条线,java,javafx,mouseevent,Java,Javafx,Mouseevent,这个想法是在鼠标上画一个球 从它的中心开始画一条线,直到它在鼠标拖动的处理程序中释放。 但它确实完全相反,我并不是简单地理解它——它首先画了一条线,在我释放鼠标后,球出现了。 有人看到问题出在哪里了吗 public class Step extends Application { public static void main(String[] args) { launch(args); } @Override public void star
public class Step extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Canvas layer1 = new Canvas(500, 500);
Group root = new Group();
root.getChildren().add(layer1);
Ball c_ball = new Ball(0, 0, 50, 0, 0);
Arrow arrow = new Arrow(0, 0, 0, 0);
layer1.addEventHandler(MouseEvent.MOUSE_CLICKED,
ev -> {
c_ball.x = ev.getX();
c_ball.y = ev.getY();
arrow.start_x = ev.getX();
arrow.start_y = ev.getY();
GraphicsContext gc = layer1.getGraphicsContext2D();
gc.setFill(Color.DARKCYAN);
gc.fillOval(c_ball.x - c_ball.size / 2, c_ball.y - c_ball.size / 2, c_ball.size, c_ball.size);
});
layer1.addEventHandler(MouseEvent.MOUSE_DRAGGED,
ev -> {
GraphicsContext gc_arr = layer1.getGraphicsContext2D();
gc_arr.clearRect(0, 0, layer1.getWidth(), layer1.getHeight());
gc_arr.strokeLine(arrow.start_x, arrow.start_y, ev.getX(), ev.getY());
});
Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
stage.show();
}
}
这是班级舞会:
public class Ball {
public double x, y;
public double dx, dy;
public double size;
public Ball(double x, double y, double size, double dx, double dy) {
this.x = x;
this.y = y;
this.size = size;
this.dx = dx;
this.dy = dy;
}}
和箭
public class Arrow {
public double start_x, start_y;
public double end_x, end_y;
public Arrow(double x1, double y1, double x2, double y2) {
this.start_x = x1;
this.start_y = y1;
this.end_x = x2;
this.end_y = y2;
}}
查看MouseEvent.MOUSE_单击的文档,您将看到: 事件类型javafx.scene.input.MouseEvent.MOUSE\u单击 单击鼠标按钮(按下并单击)时发生此事件 在同一节点上发布)。此事件提供了一个类似于 任何节点的行为。请注意,即使长时间拖动也会生成单击 事件(它被传递到鼠标所在的最顶端节点) 按下并释放) 您正在查找的鼠标事件是
MouseEvent。按下鼠标,但在这种情况下,您的代码也无法工作。原因是在调用gc_arr.clearRect(0,0,layer1.getWidth(),layer1.getHeight())时,清除了鼠标拖动事件中的所有内容代码>。因此,您将绘制圆,但您将清除画布,只绘制线。如果删除该行,则每次拖动鼠标时都会有多行,但这是另一个问题
你需要后退一大步,想想,我真的需要用Canvas实现我的程序吗
如果答案是是您需要将所有组件保存在一个列表(或一些数据结构,如数组等)中,当您想要更改某些内容时,您需要更新对象并重新绘制所有内容
如果答案是否,则您采取了正确的方法,您需要将画布更改为锚定平面或窗格等,只需直接在窗格上添加节点(圆、线等)
这里有一个简单的例子,用锚烷代替帆布
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class ShapesTest extends Application {
public static void main(String[] args) {
launch(args);
}
private double arrayStartX;
private double arrayStartY;
private AnchorPane root;
private Line l;
@Override
public void start(Stage stage) {
root = new AnchorPane();
root.addEventHandler(MouseEvent.MOUSE_PRESSED, ev -> {
addBall(ev.getX(), ev.getY());
arrayStartX = ev.getX();
arrayStartY = ev.getY();
});
root.addEventHandler(MouseEvent.MOUSE_DRAGGED, ev -> {
if (l == null) {
addLine(ev.getX(), ev.getY());
} else {
l.setEndX(ev.getX());
l.setEndY(ev.getY());
}
});
root.addEventHandler(MouseEvent.MOUSE_RELEASED, ev -> {
l = null;
});
Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
stage.show();
}
private void addLine(double x, double y) {
l = new Line(arrayStartX, arrayStartY, x, y);
root.getChildren().add(l);
}
private void addBall(double x, double y) {
Circle c = new Circle(x, y, 15);
c.fillProperty().set(Color.DARKCYAN);
root.getChildren().add(c);
}
}
在上面的示例中,如果您愿意,您可以在自己的自定义对象上保留圆圈和线条信息,然后在释放鼠标时对每个球应用物理。您可以提供球和箭头类吗?@aKilleR将这些添加到描述中,这样就可以解决这个确切的问题,但是如果你想要多行,它就不起作用了。如果你愿意,我可以把密码作为答案贴出来。现在看起来像这样:。在它画出第一对球线,并试图画出另一对球线后,由于clearRect
的原因,这条线消失了,但是你的进场可能走错了方向。画布不是这种交互式绘图的正确概念。你为什么不使用场景图?@JKostikiadis我认为我需要使用画布作为层,因为稍后会有很多球在背景上反弹,但我仍然必须在上层绘制新的球,而不会干扰(停止背景上的反弹)@mipa计划是从上层清除新的,并将其添加到背面的弹跳球中…但这只是一个想法,不知道它是否能以这种方式工作我理解你的观点,但这对Canvas来说仍然是一个巨大的头痛相信我。只需在窗格上添加节点并操纵它们的属性(宽度、高度、位置等)就会容易得多。您可以在使用窗格时轻松添加新的一个,所有您需要做的是不考虑背景球和您要添加的球之间的碰撞。@ MIPA我用一个小例子更新了我的答案,也许您可以用它作为您自己实现的开始。我希望它会有用。