单击绘制的对象
我有一个名为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
受到曲线的限制,您知道如何相交(或确定一个点是在一侧还是另一侧),则可以使用奇偶规则 。 从不受平行于直线的任何方向投射测试点的射线。 如果交叉点的数量是奇数,则该点在内部。 如果交叉点的数量是偶数,则该点在外面。
内置类实现此方法,因此您可以使用/扩展Polygon
, Ellipse2D.Double
或RoundRectangle2D.Double
类,并使用填充的多边形/椭圆/圆形矩形来了解其内部。