单击绘制的对象

我有一个名为Shape的类,它inheritance自JPanel。

许多子类反过来扩展Shape类,每种类型的形状一个。

每个形状都有自己的overriden paint()方法,它绘制相应的形状。

我希望能够点击任何形状,我现在正试图实现这个逻辑。 请注意,每个形状都已添加到arrayList中。

但是,即使我在形状内部明确单击,contains语句也始终返回false。

有任何想法吗?

永远不要覆盖JPanel paint()而不是paintComponent(..)

我不太确定我理解但是我做了一个简短的例子,我希望能有所帮助。 基本上它是一个带有DrawingPanel的简单JFrame (我自己的类扩展了JPanel并且绘制了形状)。 这个面板将创建形状(只有2个用于测试)将它们添加到ArrayList并通过paintComponent(..)for循环将它们绘制到JPanel ,它还有一个MouseAdapter来检查用户mouseClicked(..) evnets上的JPanel 。 单击时,我们遍历ArrayList每个Shape并检查Shape是否包含该点,如果是,则打印其类名并使用instance of检查单击的Shape类型并打印相应的消息:

在此处输入图像描述

输出 (点击两个形状后):

单击java.awt.geom.Rectangle2D $ Double

单击一个矩形

单击java.awt.geom.Ellipse2D $ Double

点击一个圆圈

ShapeClicker.java:

 import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class ShapeClicker { public ShapeClicker() { JFrame frame = new JFrame(); frame.setTitle("Shape Clicker"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); initComponents(frame); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { //create frame and components on EDT SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new ShapeClicker(); } }); } private void initComponents(JFrame frame) { frame.add(new ShapePanel()); } } //custom panel class ShapePanel extends JPanel { private Shape rect = new Rectangle2D.Double(50, 100, 200, 100); private Shape cirlce = new Ellipse2D.Double(260, 100, 100, 100); private Dimension dim = new Dimension(450, 300); private final ArrayList shapes; public ShapePanel() { shapes = new ArrayList<>(); shapes.add(rect); shapes.add(cirlce); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent me) { super.mouseClicked(me); for (Shape s : shapes) { if (s.contains(me.getPoint())) {//check if mouse is clicked within shape //we can either just print out the object class name System.out.println("Clicked a "+s.getClass().getName()); //or check the shape class we are dealing with using instance of with nested if if (s instanceof Rectangle2D) { System.out.println("Clicked a rectangle"); } else if (s instanceof Ellipse2D) { System.out.println("Clicked a circle"); } } } } }); } @Override protected void paintComponent(Graphics grphcs) { super.paintComponent(grphcs); Graphics2D g2d = (Graphics2D) grphcs; for (Shape s : shapes) { g2d.draw(s); } } @Override public Dimension getPreferredSize() { return dim; } } 

如果要实现Shape ,则必须自己实现contains方法。 Shape的默认实现始终返回false

如果您的Shape受到曲线的限制,您知道如何相交(或确定一个点是在一侧还是另一侧),则可以使用奇偶规则 。 从不受平行于直线的任何方向投射测试点的射线。 如果交叉点的数量是奇数,则该点在内部。 如果交叉点的数量是偶数,则该点在外面。

内置类实现此方法,因此您可以使用/扩展PolygonEllipse2D.DoubleRoundRectangle2D.Double类,并使用填充的多边形/椭圆/圆形矩形来了解其内部。