0

我在 JAVA 中有一个图形应用程序,它由许多不同的形状(线、圆、弧等,通过 Graphics.drawLine()、drawArc()... 方法绘制)组成。我想在许多(如果不是全部)绘制的对象上创建鼠标悬停事件。

我在想的是在其中存储某种带有元数据的位图,并用它来确定鼠标在哪个对象上。有没有办法在 Java 中做到这一点?(每次鼠标移动循环遍历所有对象似乎不可行)。

谢谢,

约翰

4

2 回答 2

1

主色解决方案

(移自评论)

  • 创建一个与主题图像大小相同的离屏图形缓冲区(如 BufferedImage)。
  • 将所有对象绘制到此缓冲区中。每个对象都有自己的颜色。根据对象数量,您可以优化图像缓冲区:例如使用 8 位图形。
  • 按像素读取生成的图像缓冲区(例如Java - 从图像中获取像素数组)。确定当前鼠标位置的像素颜色,并将颜色索引(或 RGB 值)映射到源对象。

优点:

  • 解决方案是“像素精确”:对象边界是精确的 - 像素到像素。
  • 轻松解决重叠对象问题。只需按照所需的顺序绘制它们。
  • 对象复杂性不受限制。理论上位图也是可能的。

缺点:

  • 要移动一个对象,必须重新绘制完整的屏幕外缓冲区
  • 使用低位图像缓冲区时可以限制对象数量
于 2013-07-16T14:34:18.150 回答
1

这取决于您的规格。你没有提到这些形状是否允许重叠、移动、可以存在多少等。

解决方案a)想到的最简单的方法是将每个形状实现为JComponent后代(例如JPanel)。因此,您将拥有一个 CirclePanel、一个 ArcPanel 等扩展JPanel,并且它们中的每一个都以与现在相同的方式绘制自己。

将形状作为 JComponent 允许您向MouseListener每个将处理mouseEntered()mouseExited()事件的面板添加一个。

解决方案 b)另一方面,如果您需要在单个组件的区域上绘制所有形状(据我所知,现在就是这种情况),那么您仍然不需要遍历所有形状。您只需要引入一种算法来根据形状对它们的位置进行分类,以便能够在您的“ isMouseOver(Shape s)”测试过程中快速排除它们。

例如,假设您将区域划分为左右 2 个相等的子区域(我们称它们为瓷砖)。当您创建每个形状时,您会测试它们与哪个拼贴相交,并将此信息存储在形状和相应的拼贴中。

现在,当您需要测试鼠标是否在某个形状上时,您可以决定鼠标在哪个图块上。这样,您只需检查与左侧或右侧瓷砖相交的形状。假设您的形状在屏幕上均匀分布,您刚刚通过一次测试拒绝了 50% 的形状。

根据您拥有的形状数量,您可以使用 4 或 8 个图块,或者您甚至可以动态创建/删除图块(例如,基于有多少对象倾向于聚集在屏幕的一个区域中)。

我建议尝试第一个解决方案,因为它更容易且更清洁。如果您认为它不符合您的需求,则可以采用类似于第二种方法的方法。

于 2013-07-15T16:37:01.917 回答