作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图每秒在 Canvas 上动态显示一百万个椭圆形。我使用线程作为渲染线程,但我的问题是,几秒钟后, Canvas 卡住并停止显示。我猜缓冲区已满,无法再显示,但是如何清除缓冲区呢?测试源码如下:
public class Main extends Application {
public void start(Stage primaryStage) {
primaryStage.setTitle("Drawing Operations Test");
Group root = new Group();
Canvas canvas = new Canvas(800, 800);
GraphicsContext gc = canvas.getGraphicsContext2D();
drawShapes(gc);
root.getChildren().add(canvas);
primaryStage.setScene(new Scene(root));
primaryStage.show();
Task task2 = new Task<Void>()
{
public synchronized Void call() throws Exception {
while (true) {
Thread.sleep(1000);
Canvas canvas = gc.getCanvas();
canvas.getGraphicsContext2D().clearRect(0, 0, canvas.getHeight(), canvas.getWidth());
drawShapes(canvas.getGraphicsContext2D());
}
}
};
Thread t = new Thread(task2);
t.start();
}
private void drawShapes(GraphicsContext gc) {
gc.setFill(Color.GREEN);
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
double widthOval=1;
double heightOval = 1;
for (int i = 0; i < 500; ++i) {
for (int j = 0; j < 500; ++j) {
if (Math.random() < 0.5) {
gc.fillOval(i * widthOval, j * heightOval, widthOval, heightOval);
}
else {
gc.strokeOval(i * widthOval, j * heightOval, widthOval, heightOval);
}
}
}
}
public static void main(String[] args) {
launch(args);
}
}
有人可以帮助我吗?
提前致谢,
皮埃尔
最佳答案
(可能)出了什么问题以及如何修复它
不要使用任务和单独的线程进行绘图。对场景图(包括 Canvas )的修改必须在 JavaFX 应用程序线程上完成。而是使用 Timeline (这将在 JavaFX 应用程序线程上隐式执行其关键帧代码)。如果必须使用任务,那么至少使用 Platform.runLater将您的调用包围到修改 Activity 场景图的 JavaFX API 中。
潜在的扩展问题
每秒一百万个椭圆对于尝试在单帧中绘制可能会很多。您可能希望运行一些基准测试,看看您的目标平台的可用数字是多少(尽管我下面的示例似乎在 2014 年 Macbook Pro 上执行良好,没有出现性能问题)。
示例代码
这是一个带有时间线的更新示例,您可以尝试。它似乎对我来说工作得很好(Java 8u60,OS X 10.9.5) - 每秒渲染 250,000 个圆圈:
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.canvas.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class LotsaCircles extends Application {
private static final double SIZE = 500;
public void start(Stage stage) {
Canvas canvas = new Canvas(SIZE, SIZE);
Timeline timeline = new Timeline(
new KeyFrame(
Duration.seconds(0),
event -> drawShapes(canvas.getGraphicsContext2D())
),
new KeyFrame(Duration.seconds(1))
);
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
stage.setScene(new Scene(new Group(canvas)));
stage.show();
}
private void drawShapes(GraphicsContext gc) {
gc.clearRect(0, 0, SIZE, SIZE);
gc.setFill(Color.GREEN);
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
double widthOval = 1;
double heightOval = 1;
for (int i = 0; i < SIZE; ++i) {
for (int j = 0; j < SIZE; ++j) {
if (Math.random() < 0.5) {
gc.fillOval(i * widthOval, j * heightOval, widthOval, heightOval);
}
else {
gc.strokeOval(i * widthOval, j * heightOval, widthOval, heightOval);
}
}
}
}
public static void main(String[] args) {
launch(args);
}
}
关于javafx canvas 几秒钟后停止显示(我正在尝试百万个椭圆),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36048234/
3-d 中的点由 (x,y,z) 定义。任意两点 (X,Y,Z) 和 (x,y,z) 之间的距离 d 为 d= Sqrt[(X-x)^2 + (Y-y)^2 + (Z-z)^2]。现在一个文件中有一百
我是一名优秀的程序员,十分优秀!