我有一个充满大量圆圈的面板(Ellipse2D)。圆圈存储在二维数组(行和列)中。
我的目标是在将鼠标拖过它们时能够“绘制”圆圈。我最终会想要使用选择形状来改变选择形状中包含的所有圆的颜色。
我正在使用鼠标拖动监听器,它不断扫描整个2d数组,并检查圆圈内部的当前点。像这样:
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
currentColor = ColorSliderPanel.getRGB();
for (int x = 0; x < numColumns; x++) {
for (int y = 0; y < numRows; y++) {
if (circle[x][y].contains(e.getX(), e.getY())) {
circle[x][y].setColor(currentColor);
repaint();
}
}
}
}
});
上面的代码有效,但它确实很慢(1000多个圆圈),因为它检查每个对象。
必须有更好的方法。我已经阅读了一些有关四叉树的内容,但我不确定四叉树是否比我需要的更强大。
由于
我根据以下一些评论做了以下更改。 Circles现在是一个线性ArrayList。绘制方法只是填充圆圈。进行此更改可将速度提高两个数量级。它现在好多了。虽然,我仍然可以以适中的速度扫过面板并错过几个圆圈。所以我可能需要进一步优化。
Graphics2D g2d = (Graphics2D) getGraphics();
for (Circle2D c : circles) {
if (c.contains(p)) {
c.setColor(currentColor);
//Graphics2D g2d = (Graphics2D) getGraphics(); (moved)
c.draw(g2d);
}
}
答案 0 :(得分:3)
我亲自这样做的方式是这样的:
注意:迭代超过1k +圈两次几乎是瞬间的,你真正的问题在于绘制圆圈(和你奇怪的x / y存储机制)。图形I / O总是很慢,特别是Java的做法。
进一步的优化是创建一个内存位图并在那里绘制矩形,然后在主表面上一次性全部blit,以进一步减少闪烁(这是由于慢重绘传递引起的每次更新)
答案 1 :(得分:1)
几千个方法调用在当代计算机上采用大约10微秒的顺序,这绝对不是人类明显的延迟,更不用说“真的很慢”。
因此,性能问题的原因必须在其他地方 - 大概是在repaint()中,这会导致调用容器的paint()。如果这吸引了几千个圆圈,这可能需要将近一秒钟。
这就是为什么在优化之前,您应该始终测量性能瓶颈的实际位置。
答案 2 :(得分:1)
每次调用mouseDragged
时,对整个圈子进行迭代都是一种令人难以置信的浪费时间。您可以选择从JTable
开始,并开发一些方法,以便您识别MouseEvent
中包含的行和列。如果您知道列的宽度和行的高度,那么识别圆的单元格应该不难。
答案 3 :(得分:1)
此example具有可移动,可调整大小的彩色节点,可通过拖动边界矩形来选择。该实现通过显示矩形边框突出显示所选节点。在下图中,已选择绿色和黑色节点。改变颜色只是对draw()
Node
方法的简单更改。