如何在 Javafx 中提高 canvas 上的线条绘制速度
How to increase draw speed of lines on canvas in Javafx
我正在用 Javafx 制作一个基本的绘画应用程序。我想知道是否有某种方法可以提高 canvas 上线条的绘制速度。
public class MouseListener implements EventHandler<MouseEvent>{
@Override
public void handle(MouseEvent event) {
if(event.getSource() == canvas){
canvas.getParent().setCursor(Cursor.CROSSHAIR);
}
if(event.getEventType() == MouseEvent.MOUSE_PRESSED){
x1 = event.getX();
y1 = event.getY();
}else if(event.getEventType() == MouseEvent.MOUSE_MOVED){
pGraphics.reset();
x2 = event.getX();
y2 = event.getY();
mouseClick = 0;
pGraphics.drawLine(x1, y1, x2, y2);
}
}
public void drawLine(double x1, double y1, double x2, double y2){
gc.strokeLine(x1, y1, x2, y2);
}
public void reset()
{
gc.clearRect(0,0, gc.getCanvas().getWidth(), gc.getCanvas().getHeight());
}
如您所见,绘图非常简单,使用 MouseListener 检测线开始的 (x1, y1) 位置,设置线所在的 (x2, y2) 位置也是如此结束。如您所见,我在绘制后清除了线条,这是我的意图,因为这是应该 "show" 线条应该去的地方的函数,例如在 Microsoft Paint 中使用线条功能。不过,所有这一切的问题在于光标后面的 "laggs" 行,以及光标何时以正确的速度移动。所以问题是:这是否与我的绘制函数、canvas 绘图函数、mouseListener 的刷新率或其他完全或所有因素有关?
真的很感激对此的一些建议。
在您的简单示例中,在重置函数中使用背景色在前一条 x1,y1,x2,y2 线上绘制一条线然后绘制新线会更有效。
但是,如果您移动 1 像素,用户可能不会注意到差异。
如果用户只是在坐标处玩
x1 = 50, y1 = 50 至 x2'=51, y2'=50 或 x2''=50, y2=51
你仍然会清除整个 canvas,这对于只有 1-2 个更改的像素来说是非常愚蠢的,对于可能有数千或数百万像素的 canvas。
但是,无论哪种方式,您都可以在不对用户造成太大影响的情况下跳过一些重绘,以优化某些速度。因此,添加一个 if 来检查与当前 x2 和 y2
相比,前一个 x2 和 y2 之间的差异是否大于 x 个像素
我认为您在这里采用了完全错误的方法。将线节点放在 canvas 顶部并修改这条线的几何数据而不是不断清除 canvas 并重新绘制线会更容易和更有效。 (你还应该问问自己,在这里使用 Canvas 是否是正确的做法,但这是只有你才能决定的事情,因为你没有提供任何关于你实际想用你的 [=12 做什么的信息=].)
问题可能不是绘图速度,而是输入反应滞后,类似于问题中讨论的问题:correct way to move a node by dragging in javafx 2?
尝试链接问题答案中的一些方法,看看是否有帮助。
请注意,如果是这种情况,那么无论您使用 canvas 还是场景图都不会真正对性能问题产生影响,因为与输入事件处理相关的问题与渲染系统。
相关错误跟踪票:Performance issue when tracking mouse events。
I see you have given a solution setting the undocumented JVM flag
-Djavafx.animation.fullspeed=true
How do I even begin to do this?
这不是我编写的解决方案,请注意未记录的标志可能会在未来的 Java 版本中被删除或修改其行为(尽管在这种情况下我认为这不太可能)。尽管如此,还是值得一试。
要了解如何设置命令行标志,请参阅:Proper usage of Java -D command-line parameters and also the java man page 标题为“-Dproperty=value”的部分。
它应该像键入 java -Djavafx.animation.fullspeed=true my package.MyMainClass
或 java -Djavafx.animation.fullspeed=true myjar.jar
一样简单(当然,用我的值替换适合您的应用程序的值)。
我正在用 Javafx 制作一个基本的绘画应用程序。我想知道是否有某种方法可以提高 canvas 上线条的绘制速度。
public class MouseListener implements EventHandler<MouseEvent>{
@Override
public void handle(MouseEvent event) {
if(event.getSource() == canvas){
canvas.getParent().setCursor(Cursor.CROSSHAIR);
}
if(event.getEventType() == MouseEvent.MOUSE_PRESSED){
x1 = event.getX();
y1 = event.getY();
}else if(event.getEventType() == MouseEvent.MOUSE_MOVED){
pGraphics.reset();
x2 = event.getX();
y2 = event.getY();
mouseClick = 0;
pGraphics.drawLine(x1, y1, x2, y2);
}
}
public void drawLine(double x1, double y1, double x2, double y2){
gc.strokeLine(x1, y1, x2, y2);
}
public void reset()
{
gc.clearRect(0,0, gc.getCanvas().getWidth(), gc.getCanvas().getHeight());
}
如您所见,绘图非常简单,使用 MouseListener 检测线开始的 (x1, y1) 位置,设置线所在的 (x2, y2) 位置也是如此结束。如您所见,我在绘制后清除了线条,这是我的意图,因为这是应该 "show" 线条应该去的地方的函数,例如在 Microsoft Paint 中使用线条功能。不过,所有这一切的问题在于光标后面的 "laggs" 行,以及光标何时以正确的速度移动。所以问题是:这是否与我的绘制函数、canvas 绘图函数、mouseListener 的刷新率或其他完全或所有因素有关? 真的很感激对此的一些建议。
在您的简单示例中,在重置函数中使用背景色在前一条 x1,y1,x2,y2 线上绘制一条线然后绘制新线会更有效。
但是,如果您移动 1 像素,用户可能不会注意到差异。
如果用户只是在坐标处玩 x1 = 50, y1 = 50 至 x2'=51, y2'=50 或 x2''=50, y2=51 你仍然会清除整个 canvas,这对于只有 1-2 个更改的像素来说是非常愚蠢的,对于可能有数千或数百万像素的 canvas。
但是,无论哪种方式,您都可以在不对用户造成太大影响的情况下跳过一些重绘,以优化某些速度。因此,添加一个 if 来检查与当前 x2 和 y2
相比,前一个 x2 和 y2 之间的差异是否大于 x 个像素我认为您在这里采用了完全错误的方法。将线节点放在 canvas 顶部并修改这条线的几何数据而不是不断清除 canvas 并重新绘制线会更容易和更有效。 (你还应该问问自己,在这里使用 Canvas 是否是正确的做法,但这是只有你才能决定的事情,因为你没有提供任何关于你实际想用你的 [=12 做什么的信息=].)
问题可能不是绘图速度,而是输入反应滞后,类似于问题中讨论的问题:correct way to move a node by dragging in javafx 2?
尝试链接问题答案中的一些方法,看看是否有帮助。
请注意,如果是这种情况,那么无论您使用 canvas 还是场景图都不会真正对性能问题产生影响,因为与输入事件处理相关的问题与渲染系统。
相关错误跟踪票:Performance issue when tracking mouse events。
I see you have given a solution setting the undocumented JVM flag
-Djavafx.animation.fullspeed=true
How do I even begin to do this?
这不是我编写的解决方案,请注意未记录的标志可能会在未来的 Java 版本中被删除或修改其行为(尽管在这种情况下我认为这不太可能)。尽管如此,还是值得一试。
要了解如何设置命令行标志,请参阅:Proper usage of Java -D command-line parameters and also the java man page 标题为“-Dproperty=value”的部分。
它应该像键入 java -Djavafx.animation.fullspeed=true my package.MyMainClass
或 java -Djavafx.animation.fullspeed=true myjar.jar
一样简单(当然,用我的值替换适合您的应用程序的值)。