单击绘制的对象 [英] Clicking on a drawn object

查看:20
本文介绍了单击绘制的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 Shape 的类,它继承自 JPanel.

I've got a class called Shape which inherits from JPanel.

许多子类依次扩展了 Shape 类,每种类型的形状一个.

A number of sub-classes in turn extend the Shape classes, one for each type of shape.

每个形状都有自己重写的 paint() 方法,该方法绘制相应的形状.

Each shape has its own overriden paint() method, which draws the respective shape.

我希望能够点击任何形状,现在我正在尝试实现这个逻辑.请注意,每个形状都已添加到一个数组列表中.

I would like to be able to click on any shape, and am trying to implement this logic for now. Please note that each shape has been added to an arrayList.

然而,包含语句总是返回 false,即使我已经清楚地点击了形状内部.

However, the contains statement always returns false, even when I have clearly clicked inside the shape.

有什么想法吗?

推荐答案

Never override paint() in JPanel 而不是 paintComponent(..)

Never override paint() in JPanel rather paintComponent(..)

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

Im not quite sure I understand however I made a short example which I hope will help. Basically it is a simple JFrame with a DrawingPanel (my own class which extends JPanel and the shapes are drawn on). This panel will create shapes (only 2 for testing) add them to an ArrayList and draw them to the JPanel via paintComponent(..) and a for loop, it also has a MouseAdapter to check for user mouseClicked(..) evnets on the JPanel. When a click is made we iterate through each Shape in the ArrayList and check whether the Shape contains the point or not, and if so prints its class name and uses instance of to check what type of Shape is clicked and prints appropriate message:

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

点击了一个 java.awt.geom.Rectangle2D$Double

Clicked a java.awt.geom.Rectangle2D$Double

点击一个矩形

点击了一个 java.awt.geom.Ellipse2D$Double

Clicked a 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<Shape> 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;
    }
}

这篇关于单击绘制的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆